Showing the changes to codec/common/src/WelsThreadLib.cpp (1 of 10 files). Show all
Unified · Split
| @@ -133,11 +133,10 @@ WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) { · 132 unmodified lines | ||
| 133 | 133 | |
| 134 | 134 | WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT* event, const char* event_name) { |
| 135 | 135 | WELS_EVENT h = CreateEvent (NULL, FALSE, FALSE, NULL); |
| 136 | − | |
| 136 | + *event = h; | |
| 137 | 137 | if (h == NULL) { |
| 138 | 138 | return WELS_THREAD_ERROR_GENERAL; |
| 139 | 139 | } |
| 140 | − *event = h; | |
| 141 | 140 | return WELS_THREAD_ERROR_OK; |
| 142 | 141 | } |
| 143 | 142 | |
| @@ -148,26 +147,20 @@ WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event) { · 4 unmodified lines | ||
| 148 | 147 | return WELS_THREAD_ERROR_GENERAL; |
| 149 | 148 | } |
| 150 | 149 | |
| 151 | −WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) { | |
| 150 | +WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event, WELS_MUTEX* pMutex) { | |
| 152 | 151 | return WaitForSingleObject (*event, INFINITE); |
| 153 | 152 | } |
| 154 | 153 | |
| 155 | −WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) { | |
| 154 | +WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds, WELS_MUTEX* pMutex) { | |
| 156 | 155 | return WaitForSingleObject (*event, dwMilliseconds); |
| 157 | 156 | } |
| 158 | 157 | |
| 159 | 158 | WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, |
| 160 | − WELS_EVENT* event_list, WELS_EVENT* master_event) { | |
| 159 | + WELS_EVENT* event_list, WELS_EVENT* master_even, WELS_MUTEX* pMutext) { | |
| 161 | 160 | // Don't need/use the master event for anything, since windows has got WaitForMultipleObjects |
| 162 | 161 | return WaitForMultipleObjects (nCount, event_list, FALSE, INFINITE); |
| 163 | 162 | } |
| 164 | 163 | |
| 165 | −WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, | |
| 166 | − WELS_EVENT* event_list, WELS_EVENT* master_event) { | |
| 167 | − // Don't need/use the master event for anything, since windows has got WaitForMultipleObjects | |
| 168 | − return WaitForMultipleObjects (nCount, event_list, TRUE, INFINITE); | |
| 169 | −} | |
| 170 | − | |
| 171 | 164 | WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, const char* event_name) { |
| 172 | 165 | CloseHandle (*event); |
| 173 | 166 | |
| @@ -278,10 +271,10 @@ WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_ · 104 unmodified lines | ||
| 278 | 271 | |
| 279 | 272 | WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name) { |
| 280 | 273 | #ifdef APPLE_IOS |
| 281 | − pthread_setname_np(thread_name); | |
| 274 | + pthread_setname_np (thread_name); | |
| 282 | 275 | #endif |
| 283 | 276 | #if defined(__ANDROID__) && __ANDROID_API__ >= 9 |
| 284 | − pthread_setname_np(pthread_self(), thread_name); | |
| 277 | + pthread_setname_np (pthread_self(), thread_name); | |
| 285 | 278 | #endif |
| 286 | 279 | // do nothing |
| 287 | 280 | return WELS_THREAD_ERROR_OK; |
| @@ -299,46 +292,33 @@ WELS_THREAD_HANDLE WelsThreadSelf() { · 11 unmodified lines | ||
| 299 | 292 | |
| 300 | 293 | WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT* p_event, const char* event_name) { |
| 301 | 294 | #ifdef __APPLE__ |
| 302 | − if (p_event == NULL) { | |
| 303 | − return WELS_THREAD_ERROR_GENERAL; | |
| 304 | − } | |
| 305 | − char strSuffix[100] = { 0 }; | |
| 306 | − if (NULL == event_name) { | |
| 307 | − sprintf (strSuffix, "WelsSem%ld_p%ld", (intptr_t)p_event, (long) (getpid())); | |
| 308 | − event_name = &strSuffix[0]; | |
| 309 | − } | |
| 310 | − *p_event = sem_open (event_name, O_CREAT, (S_IRUSR | S_IWUSR)/*0600*/, 0); | |
| 311 | − if (*p_event == (sem_t*)SEM_FAILED) { | |
| 312 | − sem_unlink (event_name); | |
| 313 | − *p_event = NULL; | |
| 314 | − return WELS_THREAD_ERROR_GENERAL; | |
| 315 | − } else { | |
| 316 | − //printf("event_open:%x, %s\n", p_event, event_name); | |
| 317 | − return WELS_THREAD_ERROR_OK; | |
| 318 | − } | |
| 295 | + WELS_THREAD_ERROR_CODE err= pthread_cond_init (p_event, NULL); | |
| 296 | + return err; | |
| 319 | 297 | #else |
| 320 | 298 | WELS_EVENT event = (WELS_EVENT) malloc (sizeof (*event)); |
| 321 | − if (event == NULL) | |
| 299 | + if (event == NULL){ | |
| 300 | + *p_event = NULL; | |
| 322 | 301 | return WELS_THREAD_ERROR_GENERAL; |
| 302 | + } | |
| 323 | 303 | WELS_THREAD_ERROR_CODE err = sem_init (event, 0, 0); |
| 324 | 304 | if (!err) { |
| 325 | 305 | *p_event = event; |
| 326 | 306 | return err; |
| 327 | 307 | } |
| 328 | 308 | free (event); |
| 309 | + *p_event = NULL; | |
| 329 | 310 | return err; |
| 330 | 311 | #endif |
| 331 | 312 | } |
| 332 | 313 | WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, const char* event_name) { |
| 333 | 314 | //printf("event_close:%x, %s\n", event, event_name); |
| 334 | 315 | #ifdef __APPLE__ |
| 335 | − WELS_THREAD_ERROR_CODE err = sem_close (*event); // match with sem_open | |
| 336 | − if (event_name) | |
| 337 | − sem_unlink (event_name); | |
| 316 | + WELS_THREAD_ERROR_CODE err = pthread_cond_destroy (event); | |
| 338 | 317 | return err; |
| 339 | 318 | #else |
| 340 | 319 | WELS_THREAD_ERROR_CODE err = sem_destroy (*event); // match with sem_init |
| 341 | 320 | free (*event); |
| 321 | + *event = NULL; | |
| 342 | 322 | return err; |
| 343 | 323 | #endif |
| 344 | 324 | } |
| @@ -349,37 +329,37 @@ void WelsSleep (uint32_t dwMilliSecond) { · 4 unmodified lines | ||
| 349 | 329 | |
| 350 | 330 | WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event) { |
| 351 | 331 | WELS_THREAD_ERROR_CODE err = 0; |
| 332 | +#ifdef __APPLE__ | |
| 333 | + err = pthread_cond_signal (event); | |
| 334 | +#else | |
| 352 | 335 | // int32_t val = 0; |
| 353 | 336 | // sem_getvalue(event, &val); |
| 354 | 337 | // fprintf( stderr, "before signal it, val= %d..\n",val ); |
| 355 | − err = sem_post (*event); | |
| 338 | + if (event != NULL) | |
| 339 | + err = sem_post (*event); | |
| 356 | 340 | // sem_getvalue(event, &val); |
| 357 | 341 | // fprintf( stderr, "after signal it, val= %d..\n",val ); |
| 342 | +#endif | |
| 358 | 343 | return err; |
| 359 | 344 | } |
| 360 | 345 | |
| 361 | −WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) { | |
| 346 | +WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event, WELS_MUTEX* pMutex) { | |
| 347 | +#ifdef __APPLE__ | |
| 348 | + return pthread_cond_wait (event, pMutex); | |
| 349 | +#else | |
| 362 | 350 | return sem_wait (*event); // blocking until signaled |
| 351 | +#endif | |
| 363 | 352 | } |
| 364 | 353 | |
| 365 | −WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) { | |
| 354 | +WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds, WELS_MUTEX* pMutex) { | |
| 355 | + | |
| 366 | 356 | if (dwMilliseconds != (uint32_t) - 1) { |
| 367 | − return sem_wait (*event); | |
| 368 | − } else { | |
| 369 | 357 | #if defined(__APPLE__) |
| 370 | − int32_t err = 0; | |
| 371 | − int32_t wait_count = 0; | |
| 372 | − do { | |
| 373 | − err = sem_trywait (*event); | |
| 374 | − if (WELS_THREAD_ERROR_OK == err) | |
| 375 | − break;// WELS_THREAD_ERROR_OK; | |
| 376 | − else if (wait_count > 0) | |
| 377 | − break; | |
| 378 | − usleep (dwMilliseconds * 1000); | |
| 379 | − ++ wait_count; | |
| 380 | − } while (1); | |
| 381 | − return err; | |
| 358 | + return pthread_cond_wait (event, pMutex); | |
| 382 | 359 | #else |
| 360 | + return sem_wait (*event); | |
| 361 | +#endif | |
| 362 | + } else { | |
| 383 | 363 | struct timespec ts; |
| 384 | 364 | struct timeval tv; |
| 385 | 365 | |
| @@ -389,26 +369,30 @@ WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t · 3 unmodified lines | ||
| 389 | 369 | ts.tv_sec = tv.tv_sec + ts.tv_nsec / 1000000000; |
| 390 | 370 | ts.tv_nsec %= 1000000000; |
| 391 | 371 | |
| 372 | +#if defined(__APPLE__) | |
| 373 | + return pthread_cond_timedwait (event, pMutex, &ts); | |
| 374 | +#else | |
| 392 | 375 | return sem_timedwait (*event, &ts); |
| 393 | −#endif//__APPLE__ | |
| 376 | +#endif | |
| 394 | 377 | } |
| 378 | + | |
| 395 | 379 | } |
| 396 | 380 | |
| 397 | 381 | WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, |
| 398 | − WELS_EVENT* event_list, WELS_EVENT* master_event) { | |
| 382 | + WELS_EVENT* event_list, WELS_EVENT* master_event, WELS_MUTEX* pMutex) { | |
| 399 | 383 | uint32_t nIdx = 0; |
| 400 | 384 | uint32_t uiAccessTime = 2; // 2 us once |
| 401 | 385 | |
| 402 | 386 | if (nCount == 0) |
| 403 | 387 | return WELS_THREAD_ERROR_WAIT_FAILED; |
| 404 | − | |
| 388 | +#if defined(__APPLE__) | |
| 405 | 389 | if (master_event != NULL) { |
| 406 | 390 | // This design relies on the events actually being semaphores; |
| 407 | 391 | // if multiple events in the list have been signalled, the master |
| 408 | 392 | // event should have a similar count (events in windows can't keep |
| 409 | 393 | // track of the actual count, but the master event isn't needed there |
| 410 | 394 | // since it uses WaitForMultipleObjects). |
| 411 | − int32_t err = sem_wait (*master_event); | |
| 395 | + int32_t err = pthread_cond_wait (master_event, pMutex); | |
| 412 | 396 | if (err != WELS_THREAD_ERROR_OK) |
| 413 | 397 | return err; |
| 414 | 398 | uiAccessTime = 0; // no blocking, just quickly loop through all to find the one that was signalled |
| @@ -425,7 +409,7 @@ WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, · 10 unmodified lines | ||
| 425 | 409 | * pthread_cond_timedwait() might be better choice if need |
| 426 | 410 | */ |
| 427 | 411 | do { |
| 428 | − err = sem_trywait (event_list[nIdx]); | |
| 412 | + err = pthread_cond_wait (&event_list[nIdx], pMutex); | |
| 429 | 413 | if (WELS_THREAD_ERROR_OK == err) |
| 430 | 414 | return WELS_THREAD_ERROR_WAIT_OBJECT_0 + nIdx; |
| 431 | 415 | else if (wait_count > 0 || uiAccessTime == 0) |
| @@ -446,60 +430,53 @@ WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, · 14 unmodified lines | ||
| 446 | 430 | uiAccessTime = 2; |
| 447 | 431 | } |
| 448 | 432 | } |
| 449 | − | |
| 450 | − return WELS_THREAD_ERROR_WAIT_FAILED; | |
| 451 | −} | |
| 452 | − | |
| 453 | −WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, | |
| 454 | − WELS_EVENT* event_list, WELS_EVENT* master_event) { | |
| 455 | − uint32_t nIdx = 0; | |
| 456 | − uint32_t uiCountSignals = 0; | |
| 457 | − uint32_t uiSignalFlag = 0; // UGLY: suppose maximal event number up to 32 | |
| 458 | − | |
| 459 | − if (nCount == 0 || nCount > (sizeof (uint32_t) << 3)) | |
| 460 | − return WELS_THREAD_ERROR_WAIT_FAILED; | |
| 433 | +#else | |
| 434 | + if (master_event != NULL) { | |
| 435 | + // This design relies on the events actually being semaphores; | |
| 436 | + // if multiple events in the list have been signalled, the master | |
| 437 | + // event should have a similar count (events in windows can't keep | |
| 438 | + // track of the actual count, but the master event isn't needed there | |
| 439 | + // since it uses WaitForMultipleObjects). | |
| 440 | + int32_t err = sem_wait (*master_event); | |
| 441 | + if (err != WELS_THREAD_ERROR_OK) | |
| 442 | + return err; | |
| 443 | + uiAccessTime = 0; // no blocking, just quickly loop through all to find the one that was signalled | |
| 444 | + } | |
| 461 | 445 | |
| 462 | 446 | while (1) { |
| 463 | 447 | nIdx = 0; // access each event by order |
| 464 | 448 | while (nIdx < nCount) { |
| 465 | − const uint32_t kuiBitwiseFlag = (1 << nIdx); | |
| 466 | − | |
| 467 | − if ((uiSignalFlag & kuiBitwiseFlag) != kuiBitwiseFlag) { // non-blocking mode | |
| 468 | − int32_t err = 0; | |
| 469 | −// fprintf( stderr, "sem_wait(): start to wait event %d..\n", nIdx ); | |
| 470 | − if (master_event == NULL) { | |
| 471 | − err = sem_wait (event_list[nIdx]); | |
| 472 | − } else { | |
| 473 | − err = sem_wait (*master_event); | |
| 474 | − if (err == WELS_THREAD_ERROR_OK) { | |
| 475 | − err = sem_wait (event_list[nIdx]); | |
| 476 | − if (err != WELS_THREAD_ERROR_OK) { | |
| 477 | − // We successfully waited for the master event, | |
| 478 | − // but waiting for the individual event failed (e.g. EINTR?). | |
| 479 | − // Increase the master event count so that the next retry will | |
| 480 | − // work as intended. | |
| 481 | − sem_post (*master_event); | |
| 482 | − } | |
| 483 | − } | |
| 484 | − } | |
| 485 | −// fprintf( stderr, "sem_wait(): wait event %d result %d errno %d..\n", nIdx, err, errno ); | |
| 486 | − if (WELS_THREAD_ERROR_OK == err) { | |
| 487 | −// int32_t val = 0; | |
| 488 | −// sem_getvalue(&event_list[nIdx], &val); | |
| 489 | −// fprintf( stderr, "after sem_timedwait(), event_list[%d] semaphore value= %d..\n", nIdx, val); | |
| 490 | − | |
| 491 | − uiSignalFlag |= kuiBitwiseFlag; | |
| 492 | − ++ uiCountSignals; | |
| 493 | − if (uiCountSignals >= nCount) { | |
| 494 | − return WELS_THREAD_ERROR_OK; | |
| 495 | − } | |
| 496 | − } | |
| 497 | − } | |
| 449 | + int32_t err = 0; | |
| 450 | + int32_t wait_count = 0; | |
| 451 | + | |
| 452 | + /* | |
| 453 | + * although such interface is not used in __GNUC__ like platform, to use | |
| 454 | + * pthread_cond_timedwait() might be better choice if need | |
| 455 | + */ | |
| 456 | + do { | |
| 457 | + err = sem_trywait (event_list[nIdx]); | |
| 458 | + if (WELS_THREAD_ERROR_OK == err) | |
| 459 | + return WELS_THREAD_ERROR_WAIT_OBJECT_0 + nIdx; | |
| 460 | + else if (wait_count > 0 || uiAccessTime == 0) | |
| 461 | + break; | |
| 462 | + usleep (uiAccessTime); | |
| 463 | + ++ wait_count; | |
| 464 | + } while (1); | |
| 498 | 465 | // we do need access next event next time |
| 499 | 466 | ++ nIdx; |
| 500 | 467 | } |
| 468 | + usleep (1); // switch to working threads | |
| 469 | + if (master_event != NULL) { | |
| 470 | + // A master event was used and was signalled, but none of the events in the | |
| 471 | + // list was found to be signalled, thus wait a little more when rechecking | |
| 472 | + // the list to avoid busylooping here. | |
| 473 | + // If we ever hit this codepath it's mostly a bug in the code that signals | |
| 474 | + // the events. | |
| 475 | + uiAccessTime = 2; | |
| 476 | + } | |
| 501 | 477 | } |
| 502 | 478 | |
| 479 | +#endif | |
| 503 | 480 | return WELS_THREAD_ERROR_WAIT_FAILED; |
| 504 | 481 | } |
| 505 | 482 | |
| @@ -519,7 +496,7 @@ WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* p · 13 unmodified lines | ||
| 519 | 496 | #else |
| 520 | 497 | int32_t count = 0; |
| 521 | 498 | for (int i = 0; i < CPU_SETSIZE; i++) { |
| 522 | − if (CPU_ISSET(i, &cpuset)) { | |
| 499 | + if (CPU_ISSET (i, &cpuset)) { | |
| 523 | 500 | count++; |
| 524 | 501 | } |
| 525 | 502 | } |