| 92 | u8 minWorkers = 0; |
| 93 | |
| 94 | void taskWorkerThread() |
| 95 | { |
| 96 | numWorkers++; |
| 97 | while (true) { |
| 98 | if (LightSemaphore_TryAcquire(&moreTasks, 1)) { |
| 99 | if (numWorkers <= minWorkers) { |
| 100 | freeWorkers++; |
| 101 | LightSemaphore_Acquire(&moreTasks, 1); |
| 102 | freeWorkers--; |
| 103 | } |
| 104 | else { |
| 105 | break; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | Task t = std::invoke([] { |
| 110 | auto tasks = workerTasks.lock(); |
| 111 | if (tasks->size() == 0) { |
| 112 | return Task{nullptr, nullptr}; |
| 113 | } |
| 114 | else { |
| 115 | // LIFO: pop the most recently queued task. While browsing the title |
| 116 | // list this hands a worker the folder-size job for the title the user |
| 117 | // just landed on before the now-unfocused ones queued earlier. |
| 118 | Task ret = tasks->back(); |
| 119 | tasks->pop_back(); |
| 120 | return ret; |
| 121 | } |
| 122 | }); |
| 123 | |
| 124 | if (!t.entrypoint) { |
| 125 | break; |
| 126 | } |
| 127 | |
| 128 | t.entrypoint(t.arg); |
| 129 | } |
| 130 | numWorkers--; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | bool Threads::init(u8 min, u8 max) |