| 174 | } |
| 175 | |
| 176 | bool threadSystemInit(ThreadSystem* out, const struct ThreadSystemInitDesc* desc) |
| 177 | { |
| 178 | *out = NULL; |
| 179 | if (desc->threadCount == 0) // dummy run |
| 180 | return true; |
| 181 | |
| 182 | uint64_t cpuCount = getNumCPUCores(); |
| 183 | uint64_t count = desc->threadCount; |
| 184 | |
| 185 | if (count > cpuCount) |
| 186 | count = cpuCount; |
| 187 | |
| 188 | if (count == 0) // something went wrong (maybe getNumCPUCores returned 0) |
| 189 | return false; |
| 190 | |
| 191 | struct ThreadSystemData* t = tf_calloc(1, sizeof(*t) + sizeof(ThreadHandle) * count); |
| 192 | if (!t) |
| 193 | return false; |
| 194 | |
| 195 | t->threads = (ThreadHandle*)(t + 1); |
| 196 | t->name = desc->threadName ? desc->threadName : "ThreadSystem"; |
| 197 | |
| 198 | bool success = false; |
| 199 | |
| 200 | do |
| 201 | { |
| 202 | if (!initMutex(&t->mutex)) |
| 203 | { |
| 204 | memset(&t->mutex, 0, sizeof t->mutex); |
| 205 | break; |
| 206 | } |
| 207 | |
| 208 | if (!initConditionVariable(&t->conditionTasks)) |
| 209 | { |
| 210 | memset(&t->conditionTasks, 0, sizeof t->conditionTasks); |
| 211 | break; |
| 212 | } |
| 213 | |
| 214 | if (!initConditionVariable(&t->conditionIsIdle)) |
| 215 | { |
| 216 | memset(&t->conditionIsIdle, 0, sizeof t->conditionIsIdle); |
| 217 | break; |
| 218 | } |
| 219 | |
| 220 | success = true; |
| 221 | } while (false); |
| 222 | |
| 223 | if (!success) |
| 224 | { |
| 225 | threadSystemCleanup(t); |
| 226 | } |
| 227 | |
| 228 | ThreadDesc threadDesc = { 0 }; |
| 229 | |
| 230 | threadDesc.pFunc = taskThreadFunc; |
| 231 | threadDesc.pData = t; |
| 232 | |
| 233 | #if defined(_WINDOWS) // for some reason on Windows thread name won't change after creation |
no test coverage detected