blob: 714c2bf4bc812b3e583c8bf705ee4075b40f0112 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#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;
}
|