| 143 | } |
| 144 | |
| 145 | void test_rapid_create_exit(void* /*arg*/) { |
| 146 | klog::Info("=== Stress: Rapid Create/Exit Test ==="); |
| 147 | |
| 148 | auto& tm = TaskManagerSingleton::instance(); |
| 149 | auto* self = tm.GetCurrentTask(); |
| 150 | if (!self) { |
| 151 | klog::Err("test_rapid_create_exit: Cannot get current task"); |
| 152 | g_tests_failed++; |
| 153 | g_tests_completed++; |
| 154 | sys_exit(1); |
| 155 | } |
| 156 | |
| 157 | bool passed = true; |
| 158 | constexpr int kIterations = 10; |
| 159 | |
| 160 | for (int i = 0; i < kIterations; ++i) { |
| 161 | auto task = kstd::make_unique<TaskControlBlock>( |
| 162 | "RapidExit", 10, rapid_exit_work, reinterpret_cast<void*>(i)); |
| 163 | task->aux->parent_pid = self->pid; |
| 164 | task->aux->pgid = self->aux->pgid; |
| 165 | auto* raw = task.get(); |
| 166 | tm.AddTask(std::move(task)); |
| 167 | Pid pid = raw->pid; |
| 168 | |
| 169 | int status = 0; |
| 170 | int timeout = 100; |
| 171 | while (timeout-- > 0) { |
| 172 | auto result = tm.Wait(pid, &status, false, false); |
| 173 | if (result.has_value() && result.value() == pid) { |
| 174 | break; |
| 175 | } |
| 176 | (void)sys_sleep(10); |
| 177 | } |
| 178 | |
| 179 | if (timeout <= 0) { |
| 180 | klog::Err("test_rapid_create_exit: timed out waiting for task {}", pid); |
| 181 | passed = false; |
| 182 | break; |
| 183 | } |
| 184 | |
| 185 | if (status != i) { |
| 186 | klog::Err( |
| 187 | "test_rapid_create_exit: FAIL - iteration {}: exit code={}, " |
| 188 | "expected {}", |
| 189 | i, status, i); |
| 190 | passed = false; |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | if (passed) { |
| 195 | klog::Info("Stress: Rapid Create/Exit Test: PASSED"); |
| 196 | } else { |
| 197 | klog::Err("Stress: Rapid Create/Exit Test: FAILED"); |
| 198 | g_tests_failed++; |
| 199 | } |
| 200 | |
| 201 | g_tests_completed++; |
| 202 | sys_exit(passed ? 0 : 1); |