| 293 | } |
| 294 | |
| 295 | void threadSystemAddTasks(ThreadSystem thandle, TaskFunc func, uint64_t count, uint64_t userSize, void* users) |
| 296 | { |
| 297 | if (count == 0) |
| 298 | return; |
| 299 | if (!VERIFY(func)) |
| 300 | return; |
| 301 | |
| 302 | struct ThreadSystemData* t = thandle; |
| 303 | |
| 304 | if (!t) // dummy run |
| 305 | { |
| 306 | for (uint64_t ti = 0; ti < count; ++ti) |
| 307 | func((uint8_t*)users + ti * userSize, 0); |
| 308 | return; |
| 309 | } |
| 310 | |
| 311 | acquireMutex(&t->mutex); |
| 312 | |
| 313 | uint64_t offset = t->tasksQueued; |
| 314 | |
| 315 | t->tasksQueued += count; |
| 316 | |
| 317 | uint64_t len = arrlenu(t->tasks); |
| 318 | |
| 319 | if (t->tasksQueued > len) |
| 320 | { |
| 321 | // Resize the task array to a multiple of OPTIMAL_TASK_SLOTS_COUNT that is large enough to contain all of the requested tasks. |
| 322 | uint64_t newTasksLength = t->tasksQueued / OPTIMAL_TASK_SLOTS_COUNT; |
| 323 | newTasksLength += (t->tasksQueued % OPTIMAL_TASK_SLOTS_COUNT) == 0 ? 0 : 1; |
| 324 | newTasksLength *= OPTIMAL_TASK_SLOTS_COUNT; |
| 325 | arrsetlen(t->tasks, newTasksLength); |
| 326 | } |
| 327 | |
| 328 | for (uint64_t ti = 0; ti < count; ++ti) |
| 329 | { |
| 330 | t->tasks[offset + ti] = (struct ThreadSystemTask){ |
| 331 | func, |
| 332 | users ? ((uint8_t*)users + ti * userSize) : NULL, |
| 333 | }; |
| 334 | } |
| 335 | |
| 336 | if (count == 1) |
| 337 | wakeOneConditionVariable(&t->conditionTasks); |
| 338 | else |
| 339 | wakeAllConditionVariable(&t->conditionTasks); |
| 340 | |
| 341 | releaseMutex(&t->mutex); |
| 342 | return; |
| 343 | } |
| 344 | |
| 345 | bool threadSystemAssist(ThreadSystem thandle) |
| 346 | { |
no test coverage detected