void incr(struct args *p) { int i; static int j; for (i = 0; i < 10000; i++) { Sem_wait(p->mutex); *p->ip = *p->ip + 1; Sem_signal(p->mutex); } printf("%d:(%d:y)=%d\n", j, Thread_self(), y); j++; }
void Sem_wait(T *s) { DWORD result; Thread_T current = Thread_self(); assert(s); testalert(current); result = WaitForSingleObject(s->queue, INFINITE); assert(result != WAIT_FAILED); ENTERCRITICAL; if (current->alerted) { BOOL result; current->alerted = 0; LEAVECRITICAL; result = ReleaseSemaphore(s->queue, 1, NULL); assert(result == TRUE); RAISE(Thread_Alerted); } LEAVECRITICAL; }
int Thread_join(T t) { T current = Thread_self(); assert(root); assert(t != current); testalert(current); if (t != NULL) { ENTERCRITICAL; if (t->handle == t) { HANDLE join = t->join; DWORD result; assert(current->link == NULL); current->link = t->joinlist; t->joinlist = current; LEAVECRITICAL; result = WaitForSingleObject(join, INFINITE); assert(result != WAIT_FAILED); testalert(current); return current->code; } else { LEAVECRITICAL; return -1; } } ENTERCRITICAL; if (nthreads > 1) { DWORD result; assert(join0count == 0); join0count++; LEAVECRITICAL; result = WaitForSingleObject(join0, INFINITE); assert(result != WAIT_FAILED); ENTERCRITICAL; join0count--; LEAVECRITICAL; testalert(current); } else { assert(join0count == 0); LEAVECRITICAL; return 0; } }
void Thread_exit(int code) { BOOL result; T current = Thread_self(); removeThread(current); ENTERCRITICAL; if (current->joinlist != NULL) { T t, n; int count = 0; assert(current->join); for (t = current->joinlist; t != NULL; t = n) { t->code = code; n = t->link; t->link = NULL; count++; } current->joinlist = NULL; result = ReleaseSemaphore(current->join, count, NULL); assert(result == TRUE); } result = CloseHandle(current->join); assert(result == TRUE); current->join = NULL; if (join0count > 0 && nthreads == 1) { assert(join0count == 1); result = ReleaseSemaphore(join0, 1, NULL); assert(result == TRUE); } if (nthreads == 0) { result = CloseHandle(join0); assert(result == TRUE); } FREE(current); LEAVECRITICAL; _endthreadex(code); }
static unsigned long _threadID() { return (unsigned long)Thread_self(); }