#include #include #include #include #include "thread_internal.h" int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { int ret=0; _pthread_descr td; pthread_attr_t default_attr; __THREAD_INIT(); if (start_routine==0) { return EINVAL; } td = __thread_get_free(); if (td) { td->go.__spinlock=PTHREAD_SPIN_LOCKED; if (!(attr)) { pthread_attr_init(&default_attr); attr=&default_attr; } if ((td->policy!=SCHED_OTHER)&&(td->priority==0)) { return EINVAL; } if (attr->__inheritsched==PTHREAD_INHERIT_SCHED) { _pthread_descr this = __thread_self(); td->policy = this->policy; td->priority = this->priority; } else { td->policy = attr->__schedpolicy; td->priority = attr->__schedparam.sched_priority; } td->func = start_routine; td->arg = arg; td->detached = attr->__detachstate; td->stack_size = attr->__stacksize; if (!(attr->__stackaddr)) { char *stack=(char*)malloc(td->stack_size); if (!(stack)) { return EINVAL; } td->stack_begin = stack; #ifdef __parisc__ td->stack_addr = stack; #else td->stack_addr = stack+td->stack_size; #endif } else { td->stack_begin = 0; td->stack_addr = attr->__stackaddr; } ret = signal_manager_thread(td); if (ret>1) *thread=ret; else { ++td->exited; /* mark as exited */ __thread_cleanup(td); if (ret<0) return (*(__errno_location())); return EAGAIN; } } else return EAGAIN; return 0; }