41 #define __FILE_ID__ "ythread" 46 static DWORD yTlsBucket = TLS_OUT_OF_INDEXES;
51 *
event = CreateEvent(0, 0, 0, 0);
56 *
event = CreateEvent(0, TRUE, initialState != 0, 0);
81 res = WaitForSingleObject(*ev, usec);
82 return res == WAIT_OBJECT_0;
93 *th_hdl = CreateThread(
96 (LPTHREAD_START_ROUTINE)fun,
100 if (*th_hdl == NULL) {
109 CloseHandle(*th_hdl);
115 DWORD result = WaitForSingleObject(*th, INFINITE);
116 return result == WAIT_OBJECT_0 ? 0 : -1;
121 TerminateThread(*th, 0);
129 if (yTlsBucket == TLS_OUT_OF_INDEXES) {
131 yTlsBucket = TlsAlloc();
133 tls_ptr = TlsGetValue(yTlsBucket);
138 TlsSetValue(yTlsBucket, ((u8*)NULL) + res);
141 return (
int)(tls_ptr - ((u8*)NULL));
146 #include <sys/time.h> 156 pthread_key_create(&
yTsdKey, NULL);
161 pthread_cond_init(&ev->
cond, NULL);
162 pthread_mutex_init(&ev->
mtx, NULL);
169 pthread_cond_init(&ev->
cond, NULL);
170 pthread_mutex_init(&ev->
mtx, NULL);
171 ev->
verif = initialState > 0;
177 pthread_mutex_lock(&ev->
mtx);
182 pthread_cond_signal(&ev->
cond);
183 pthread_mutex_unlock(&ev->
mtx);
189 pthread_mutex_lock(&ev->
mtx);
191 pthread_mutex_unlock(&ev->
mtx);
199 pthread_mutex_lock(&ev->
mtx);
203 struct timespec later;
204 gettimeofday(&now, NULL);
205 later.tv_sec = now.tv_sec + time / 1000;
206 later.tv_nsec = now.tv_usec * 1000 + (time % 1000) * 1000000;
207 if (later.tv_nsec >= 1000000000) {
209 later.tv_nsec -= 1000000000;
211 pthread_cond_timedwait(&ev->
cond, &ev->
mtx, &later);
213 pthread_cond_wait(&ev->
cond, &ev->
mtx);
219 pthread_mutex_unlock(&ev->
mtx);
225 pthread_cond_destroy(&ev->
cond);
226 pthread_mutex_destroy(&ev->
mtx);
234 pthread_attr_init(&attr);
235 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
237 if (pthread_create(th, &attr, fun, arg) != 0) {
242 pthread_attr_destroy(&attr);
255 return pthread_join(*th, NULL);
269 res = (int)((u8 *)pthread_getspecific(
yTsdKey) - (u8 *)NULL);
274 pthread_setspecific(
yTsdKey, (
void*)((u8 *)NULL + res));
361 #ifdef DEBUG_CRITICAL_SECTION 369 #define MAX_DB_CS 128 374 static u32 nbycs = 0;
377 #define CS_BREAK {while(1);} 379 #if defined(WINDOWS_API) && (_MSC_VER) 380 #define CS_BREAK { _asm {int 3}} 382 #define CS_BREAK {__asm__("int3");} 386 #define CS_ASSERT(x) if(!(x)){printf("ASSERT FAILED:%s:%d (%s:%d)\n",__FILE__ , __LINE__,fileid,lineno);dump_YCS(csptr);CS_BREAK} 387 #define CS_TRACK_NO 24 389 CRITICAL_SECTION CS_CS;
393 InitializeCriticalSection(&CS_CS);
398 DeleteCriticalSection(&CS_CS);
403 static const char* YCS_STATE_STR[] = {
409 static const char* YCS_ACTION_STR[] = {
422 const char* state_str;
424 printf(
"NULL csptr");
427 if (ycs->state <
sizeof(YCS_STATE_STR)) {
428 state_str= YCS_STATE_STR[ycs->state];
430 state_str =
"INVALID";
432 printf(
"%p:%02x: state=%s lock=%d\n", ycs, ycs->no, state_str, ycs->lock);
433 for (i = 0; i < YCS_NB_TRACE; i++) {
434 u32 action = ycs->last_actions[i].action;
435 const char* action_str =
"INVALID";
436 const char* file_str = ycs->last_actions[i].fileid;
437 if (action <
sizeof(YCS_ACTION_STR)) {
438 action_str = YCS_ACTION_STR[action];
440 if (file_str == NULL) {
443 printf(
" - %s on %s:%d (th=%d)\n", action_str,
444 file_str, ycs->last_actions[i].lineno, ycs->last_actions[i].thread);
449 static void pushCSAction(
int threadid,
const char* fileid,
int lineno,
yCRITICAL_SECTION_ST *csptr, YCS_ACTION action)
451 memmove(&csptr->last_actions[1], &csptr->last_actions[0],
sizeof(YCS_LOC)*(YCS_NB_TRACE - 1));
452 csptr->last_actions[0].thread = threadid;
453 csptr->last_actions[0].fileid = fileid;
454 csptr->last_actions[0].lineno = lineno;
455 csptr->last_actions[0].action = action;
459 void yDbgInitializeCriticalSection(
const char* fileid,
int lineno,
yCRITICAL_SECTION *csptr)
465 EnterCriticalSection(&CS_CS);
466 (*csptr)->no = nbycs++;
467 LeaveCriticalSection(&CS_CS);
468 if ((*csptr)->no == CS_TRACK_NO || CS_TRACK_NO < 0) {
469 printf(
"NEW CS on %s:%d:%p (%d)\n", fileid, lineno, (*csptr), (*csptr)->no);
472 (*csptr)->state = YCS_ALLOCATED;
473 pushCSAction(threadid, fileid, lineno, (*csptr), YCS_INIT);
477 #elif defined(WINDOWS_API) 479 InitializeCriticalSection(&((*csptr)->cs));
481 res = pthread_mutex_init(&((*csptr)->cs), NULL);
483 EnterCriticalSection(&((*csptr)->cs));
484 LeaveCriticalSection(&((*csptr)->cs));
487 res = pthread_mutex_lock(&((*csptr)->cs));
489 res = pthread_mutex_unlock(&((*csptr)->cs));
495 void yDbgEnterCriticalSection(
const char* fileid,
int lineno,
yCRITICAL_SECTION *csptr)
500 CS_ASSERT((*csptr)->no < nbycs);
501 CS_ASSERT((*csptr)->state == YCS_ALLOCATED);
503 if ((*csptr)->no == CS_TRACK_NO || CS_TRACK_NO < 0) {
504 printf(
"enter CS on %s:%d:%p (%d)\n", fileid, lineno, (*csptr), (*csptr)->no);
509 #elif defined(WINDOWS_API) 511 EnterCriticalSection(&((*csptr)->cs));
513 res = pthread_mutex_lock(&((*csptr)->cs));
516 CS_ASSERT((*csptr)->lock == 0);
518 pushCSAction(threadid, fileid, lineno, (*csptr), YCS_LOCK);
522 int yDbgTryEnterCriticalSection(
const char* fileid,
int lineno,
yCRITICAL_SECTION *csptr)
527 CS_ASSERT((*csptr)->no < nbycs);
528 CS_ASSERT((*csptr)->state == YCS_ALLOCATED);
530 if ((*csptr)->no == CS_TRACK_NO || CS_TRACK_NO < 0) {
531 printf(
"enter CS on %s:%d:%p (%d)\n", fileid, lineno, (*csptr), (*csptr)->no);
539 #elif defined(WINDOWS_API) 540 res = TryEnterCriticalSection(&((*csptr)->cs));
545 res = pthread_mutex_trylock(&((*csptr)->cs));
550 CS_ASSERT((*csptr)->lock == 0);
552 pushCSAction(threadid, fileid, lineno, (*csptr), YCS_LOCKTRY);
557 void yDbgLeaveCriticalSection(
const char* fileid,
int lineno,
yCRITICAL_SECTION *csptr)
563 CS_ASSERT((*csptr)->no < nbycs);
564 CS_ASSERT((*csptr)->state == YCS_ALLOCATED);
565 CS_ASSERT((*csptr)->lock == 1);
566 if ((*csptr)->no == CS_TRACK_NO || CS_TRACK_NO < 0) {
567 printf(
"leave CS on %s:%d:%p (%d)\n", fileid, lineno, (*csptr), (*csptr)->no);
571 pushCSAction(threadid, fileid, lineno, (*csptr), YCS_RELEASE);
576 #elif defined(WINDOWS_API) 578 LeaveCriticalSection(&((*csptr)->cs));
580 res = pthread_mutex_unlock(&((*csptr)->cs));
585 void yDbgDeleteCriticalSection(
const char* fileid,
int lineno,
yCRITICAL_SECTION *csptr)
591 CS_ASSERT((*csptr)->no < nbycs);
592 CS_ASSERT((*csptr)->state == YCS_ALLOCATED);
593 CS_ASSERT((*csptr)->lock == 0);
595 if ((*csptr)->no == CS_TRACK_NO || CS_TRACK_NO < 0) {
596 printf(
"delete CS on %s:%d:%p (%p)\n", fileid, lineno, (*csptr), &((*csptr)->cs));
602 #elif defined(WINDOWS_API) 604 DeleteCriticalSection(&((*csptr)->cs));
606 res = pthread_mutex_destroy(&((*csptr)->cs));
609 (*csptr)->state = YCS_DELETED;
610 pushCSAction(threadid, fileid, lineno, (*csptr), YCS_DELETE);
613 #elif !defined(MICROCHIP_API) 621 #if defined(WINDOWS_API) 634 #if defined(WINDOWS_API) 635 InitializeCriticalSection(&(ycsptr->
cs));
638 pthread_mutexattr_t attr;
639 pthread_mutexattr_init(&attr);
640 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
641 pthread_mutex_init(&(ycsptr->
cs), &attr);
650 #if defined(WINDOWS_API) 651 EnterCriticalSection(&(ycsptr->
cs));
653 pthread_mutex_lock(&(ycsptr->
cs));
660 #if defined(WINDOWS_API) 661 return TryEnterCriticalSection(&(ycsptr->
cs));
664 int res = pthread_mutex_trylock(&(ycsptr->
cs));
675 #if defined(WINDOWS_API) 676 LeaveCriticalSection(&(ycsptr->
cs));
678 pthread_mutex_unlock(&(ycsptr->
cs));
685 #if defined(WINDOWS_API) 686 DeleteCriticalSection(&(ycsptr->
cs));
688 pthread_mutex_destroy(&(ycsptr->
cs));
void yThreadKill(yThread *yth)
int yWaitForEvent(yEvent *ev, int time)
void yCreateEvent(yEvent *ev)
static pthread_key_t yTsdKey
static unsigned yNextThreadIdx
void yDeleteCriticalSection(yCRITICAL_SECTION *cs)
int yThreadCreate(yThread *yth, void *(*fun)(void *), void *arg)
static pthread_once_t yInitKeyOnce
static int yWaitEndThread(osThread *th)
int yTryEnterCriticalSection(yCRITICAL_SECTION *cs)
static void yKillThread(osThread *th)
int yCreateDetachedThread(void *(*fun)(void *), void *arg)
void yThreadRequestEnd(yThread *yth)
void yResetEvent(yEvent *ev)
void yLeaveCriticalSection(yCRITICAL_SECTION *cs)
void yInitializeCriticalSection(yCRITICAL_SECTION *cs)
void ySetEvent(yEvent *ev)
void yEnterCriticalSection(yCRITICAL_SECTION *cs)
void yCreateManualEvent(yEvent *ev, int initialState)
static int yCreateDetachedThreadEx(osThread *th, void *(*fun)(void *), void *arg)
static void yReleaseDetachedThreadEx(osThread *th_hdl)
void yThreadSignalEnd(yThread *yth)
void yCloseEvent(yEvent *ev)
int yThreadMustEnd(yThread *yth)
int yThreadIsRunning(yThread *yth)
void yThreadSignalStart(yThread *yth)