int dcethread_create(dcethread** _thread, dcethread_attr* attr, void *(*start_routine)(void *), void *arg) { dcethread_start_args *start_args; dcethread* thread; int detachstate; start_args = (dcethread_start_args *) malloc(sizeof(*start_args)); if (start_args == NULL) { return dcethread__set_errno(ENOMEM); } start_args->start = start_routine; start_args->data = arg; start_args->self = thread = dcethread__new(); /* Record if this thread was created joinably */ if (!attr || (pthread_attr_getdetachstate(attr, &detachstate), detachstate == PTHREAD_CREATE_JOINABLE)) { thread->flag.joinable = 1; } /* If thread is joinable, give it an extra reference */ if (thread->flag.joinable) { thread->refs++; } if (dcethread__set_errno(pthread_create((pthread_t*) &thread->pthread, attr, proxy_start, start_args))) { dcethread__delete(thread); free(start_args); return -1; } DCETHREAD_TRACE("Thread %p: created (pthread %lu)", thread, (unsigned long) thread->pthread); dcethread__lock(thread); while (thread->state == DCETHREAD_STATE_CREATED) { dcethread__wait(thread); } dcethread__unlock(thread); DCETHREAD_TRACE("Thread %p: started", thread); *_thread = thread; return dcethread__set_errno(0); }
dcethread* dcethread__self(void) { dcethread* thread; /* Ensure thread system is initialized */ dcethread__init(); /* Get self pointer from TLS */ thread = (dcethread*) pthread_getspecific(dcethread_self_key); if (!thread) { /* Lazily create it if it didn't already exist */ thread = dcethread__new(); thread->pthread = pthread_self(); pthread_setspecific(dcethread_self_key, (void*) thread); thread->state = DCETHREAD_STATE_ACTIVE; } return thread; }