正在显示
2 个修改的文件
包含
291 行增加
和
307 行删除
@@ -46,7 +46,6 @@ | @@ -46,7 +46,6 @@ | ||
46 | #include <sys/mman.h> | 46 | #include <sys/mman.h> |
47 | #include "common.h" | 47 | #include "common.h" |
48 | 48 | ||
49 | - | ||
50 | /* How much space to leave between the stacks, at each end */ | 49 | /* How much space to leave between the stacks, at each end */ |
51 | #define REDZONE _ST_PAGE_SIZE | 50 | #define REDZONE _ST_PAGE_SIZE |
52 | 51 | ||
@@ -58,116 +57,118 @@ static char *_st_new_stk_segment(int size); | @@ -58,116 +57,118 @@ static char *_st_new_stk_segment(int size); | ||
58 | 57 | ||
59 | _st_stack_t *_st_stack_new(int stack_size) | 58 | _st_stack_t *_st_stack_new(int stack_size) |
60 | { | 59 | { |
61 | - _st_clist_t *qp; | ||
62 | - _st_stack_t *ts; | ||
63 | - int extra; | ||
64 | - | ||
65 | - for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) { | ||
66 | - ts = _ST_THREAD_STACK_PTR(qp); | ||
67 | - if (ts->stk_size >= stack_size) { | ||
68 | - /* Found a stack that is big enough */ | ||
69 | - ST_REMOVE_LINK(&ts->links); | ||
70 | - _st_num_free_stacks--; | ||
71 | - ts->links.next = NULL; | ||
72 | - ts->links.prev = NULL; | ||
73 | - return ts; | 60 | + _st_clist_t *qp; |
61 | + _st_stack_t *ts; | ||
62 | + int extra; | ||
63 | + | ||
64 | + for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) { | ||
65 | + ts = _ST_THREAD_STACK_PTR(qp); | ||
66 | + if (ts->stk_size >= stack_size) { | ||
67 | + /* Found a stack that is big enough */ | ||
68 | + ST_REMOVE_LINK(&ts->links); | ||
69 | + _st_num_free_stacks--; | ||
70 | + ts->links.next = NULL; | ||
71 | + ts->links.prev = NULL; | ||
72 | + return ts; | ||
73 | + } | ||
74 | } | 74 | } |
75 | - } | ||
76 | - | ||
77 | - /* Make a new thread stack object. */ | ||
78 | - if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL) | ||
79 | - return NULL; | ||
80 | - extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; | ||
81 | - ts->vaddr_size = stack_size + 2*REDZONE + extra; | ||
82 | - ts->vaddr = _st_new_stk_segment(ts->vaddr_size); | ||
83 | - if (!ts->vaddr) { | ||
84 | - free(ts); | ||
85 | - return NULL; | ||
86 | - } | ||
87 | - ts->stk_size = stack_size; | ||
88 | - ts->stk_bottom = ts->vaddr + REDZONE; | ||
89 | - ts->stk_top = ts->stk_bottom + stack_size; | ||
90 | - | 75 | + |
76 | + /* Make a new thread stack object. */ | ||
77 | + if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL) { | ||
78 | + return NULL; | ||
79 | + } | ||
80 | + extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; | ||
81 | + ts->vaddr_size = stack_size + 2*REDZONE + extra; | ||
82 | + ts->vaddr = _st_new_stk_segment(ts->vaddr_size); | ||
83 | + if (!ts->vaddr) { | ||
84 | + free(ts); | ||
85 | + return NULL; | ||
86 | + } | ||
87 | + ts->stk_size = stack_size; | ||
88 | + ts->stk_bottom = ts->vaddr + REDZONE; | ||
89 | + ts->stk_top = ts->stk_bottom + stack_size; | ||
90 | + | ||
91 | #ifdef DEBUG | 91 | #ifdef DEBUG |
92 | - mprotect(ts->vaddr, REDZONE, PROT_NONE); | ||
93 | - mprotect(ts->stk_top + extra, REDZONE, PROT_NONE); | 92 | + mprotect(ts->vaddr, REDZONE, PROT_NONE); |
93 | + mprotect(ts->stk_top + extra, REDZONE, PROT_NONE); | ||
94 | #endif | 94 | #endif |
95 | - | ||
96 | - if (extra) { | ||
97 | - long offset = (random() % extra) & ~0xf; | ||
98 | - | ||
99 | - ts->stk_bottom += offset; | ||
100 | - ts->stk_top += offset; | ||
101 | - } | ||
102 | - | ||
103 | - return ts; | 95 | + |
96 | + if (extra) { | ||
97 | + long offset = (random() % extra) & ~0xf; | ||
98 | + | ||
99 | + ts->stk_bottom += offset; | ||
100 | + ts->stk_top += offset; | ||
101 | + } | ||
102 | + | ||
103 | + return ts; | ||
104 | } | 104 | } |
105 | 105 | ||
106 | - | ||
107 | /* | 106 | /* |
108 | * Free the stack for the current thread | 107 | * Free the stack for the current thread |
109 | */ | 108 | */ |
110 | void _st_stack_free(_st_stack_t *ts) | 109 | void _st_stack_free(_st_stack_t *ts) |
111 | { | 110 | { |
112 | - if (!ts) | ||
113 | - return; | ||
114 | - | ||
115 | - /* Put the stack on the free list */ | ||
116 | - ST_APPEND_LINK(&ts->links, _st_free_stacks.prev); | ||
117 | - _st_num_free_stacks++; | 111 | + if (!ts) { |
112 | + return; | ||
113 | + } | ||
114 | + | ||
115 | + /* Put the stack on the free list */ | ||
116 | + ST_APPEND_LINK(&ts->links, _st_free_stacks.prev); | ||
117 | + _st_num_free_stacks++; | ||
118 | } | 118 | } |
119 | 119 | ||
120 | - | ||
121 | static char *_st_new_stk_segment(int size) | 120 | static char *_st_new_stk_segment(int size) |
122 | { | 121 | { |
123 | #ifdef MALLOC_STACK | 122 | #ifdef MALLOC_STACK |
124 | - void *vaddr = malloc(size); | ||
125 | -#else | ||
126 | - static int zero_fd = -1; | ||
127 | - int mmap_flags = MAP_PRIVATE; | ||
128 | - void *vaddr; | ||
129 | - | ||
130 | -#if defined (MD_USE_SYSV_ANON_MMAP) | ||
131 | - if (zero_fd < 0) { | ||
132 | - if ((zero_fd = open("/dev/zero", O_RDWR, 0)) < 0) | ||
133 | - return NULL; | ||
134 | - fcntl(zero_fd, F_SETFD, FD_CLOEXEC); | ||
135 | - } | ||
136 | -#elif defined (MD_USE_BSD_ANON_MMAP) | ||
137 | - mmap_flags |= MAP_ANON; | 123 | + void *vaddr = malloc(size); |
138 | #else | 124 | #else |
139 | -#error Unknown OS | 125 | + static int zero_fd = -1; |
126 | + int mmap_flags = MAP_PRIVATE; | ||
127 | + void *vaddr; | ||
128 | + | ||
129 | + #if defined (MD_USE_SYSV_ANON_MMAP) | ||
130 | + if (zero_fd < 0) { | ||
131 | + if ((zero_fd = open("/dev/zero", O_RDWR, 0)) < 0) { | ||
132 | + return NULL; | ||
133 | + } | ||
134 | + fcntl(zero_fd, F_SETFD, FD_CLOEXEC); | ||
135 | + } | ||
136 | + #elif defined (MD_USE_BSD_ANON_MMAP) | ||
137 | + mmap_flags |= MAP_ANON; | ||
138 | + #else | ||
139 | + #error Unknown OS | ||
140 | + #endif | ||
141 | + | ||
142 | + vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, zero_fd, 0); | ||
143 | + if (vaddr == (void *)MAP_FAILED) { | ||
144 | + return NULL; | ||
145 | + } | ||
146 | + | ||
140 | #endif | 147 | #endif |
141 | - | ||
142 | - vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, zero_fd, 0); | ||
143 | - if (vaddr == (void *)MAP_FAILED) | ||
144 | - return NULL; | ||
145 | - | ||
146 | -#endif /* MALLOC_STACK */ | ||
147 | - | ||
148 | - return (char *)vaddr; | 148 | + |
149 | + return (char *)vaddr; | ||
149 | } | 150 | } |
150 | 151 | ||
151 | - | ||
152 | /* Not used */ | 152 | /* Not used */ |
153 | #if 0 | 153 | #if 0 |
154 | void _st_delete_stk_segment(char *vaddr, int size) | 154 | void _st_delete_stk_segment(char *vaddr, int size) |
155 | { | 155 | { |
156 | #ifdef MALLOC_STACK | 156 | #ifdef MALLOC_STACK |
157 | - free(vaddr); | 157 | + free(vaddr); |
158 | #else | 158 | #else |
159 | - (void) munmap(vaddr, size); | 159 | + (void) munmap(vaddr, size); |
160 | #endif | 160 | #endif |
161 | } | 161 | } |
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | int st_randomize_stacks(int on) | 164 | int st_randomize_stacks(int on) |
165 | { | 165 | { |
166 | - int wason = _st_randomize_stacks; | ||
167 | - | ||
168 | - _st_randomize_stacks = on; | ||
169 | - if (on) | ||
170 | - srandom((unsigned int) st_utime()); | ||
171 | - | ||
172 | - return wason; | 166 | + int wason = _st_randomize_stacks; |
167 | + | ||
168 | + _st_randomize_stacks = on; | ||
169 | + if (on) { | ||
170 | + srandom((unsigned int) st_utime()); | ||
171 | + } | ||
172 | + | ||
173 | + return wason; | ||
173 | } | 174 | } |
@@ -44,326 +44,309 @@ | @@ -44,326 +44,309 @@ | ||
44 | #include <errno.h> | 44 | #include <errno.h> |
45 | #include "common.h" | 45 | #include "common.h" |
46 | 46 | ||
47 | - | ||
48 | extern time_t _st_curr_time; | 47 | extern time_t _st_curr_time; |
49 | extern st_utime_t _st_last_tset; | 48 | extern st_utime_t _st_last_tset; |
50 | extern int _st_active_count; | 49 | extern int _st_active_count; |
51 | 50 | ||
52 | static st_utime_t (*_st_utime)(void) = NULL; | 51 | static st_utime_t (*_st_utime)(void) = NULL; |
53 | 52 | ||
54 | - | ||
55 | /***************************************** | 53 | /***************************************** |
56 | * Time functions | 54 | * Time functions |
57 | */ | 55 | */ |
58 | 56 | ||
59 | st_utime_t st_utime(void) | 57 | st_utime_t st_utime(void) |
60 | { | 58 | { |
61 | - if (_st_utime == NULL) { | 59 | + if (_st_utime == NULL) { |
62 | #ifdef MD_GET_UTIME | 60 | #ifdef MD_GET_UTIME |
63 | - MD_GET_UTIME(); | 61 | + MD_GET_UTIME(); |
64 | #else | 62 | #else |
65 | -#error Unknown OS | 63 | + #error Unknown OS |
66 | #endif | 64 | #endif |
67 | - } | ||
68 | - | ||
69 | - return (*_st_utime)(); | 65 | + } |
66 | + | ||
67 | + return (*_st_utime)(); | ||
70 | } | 68 | } |
71 | 69 | ||
72 | - | ||
73 | int st_set_utime_function(st_utime_t (*func)(void)) | 70 | int st_set_utime_function(st_utime_t (*func)(void)) |
74 | { | 71 | { |
75 | - if (_st_active_count) { | ||
76 | - errno = EINVAL; | ||
77 | - return -1; | ||
78 | - } | ||
79 | - | ||
80 | - _st_utime = func; | ||
81 | - | ||
82 | - return 0; | 72 | + if (_st_active_count) { |
73 | + errno = EINVAL; | ||
74 | + return -1; | ||
75 | + } | ||
76 | + | ||
77 | + _st_utime = func; | ||
78 | + | ||
79 | + return 0; | ||
83 | } | 80 | } |
84 | 81 | ||
85 | - | ||
86 | st_utime_t st_utime_last_clock(void) | 82 | st_utime_t st_utime_last_clock(void) |
87 | { | 83 | { |
88 | - return _ST_LAST_CLOCK; | 84 | + return _ST_LAST_CLOCK; |
89 | } | 85 | } |
90 | 86 | ||
91 | - | ||
92 | int st_timecache_set(int on) | 87 | int st_timecache_set(int on) |
93 | { | 88 | { |
94 | - int wason = (_st_curr_time) ? 1 : 0; | ||
95 | - | ||
96 | - if (on) { | ||
97 | - _st_curr_time = time(NULL); | ||
98 | - _st_last_tset = st_utime(); | ||
99 | - } else | ||
100 | - _st_curr_time = 0; | ||
101 | - | ||
102 | - return wason; | 89 | + int wason = (_st_curr_time) ? 1 : 0; |
90 | + | ||
91 | + if (on) { | ||
92 | + _st_curr_time = time(NULL); | ||
93 | + _st_last_tset = st_utime(); | ||
94 | + } else { | ||
95 | + _st_curr_time = 0; | ||
96 | + } | ||
97 | + | ||
98 | + return wason; | ||
103 | } | 99 | } |
104 | 100 | ||
105 | - | ||
106 | time_t st_time(void) | 101 | time_t st_time(void) |
107 | { | 102 | { |
108 | - if (_st_curr_time) | ||
109 | - return _st_curr_time; | ||
110 | - | ||
111 | - return time(NULL); | 103 | + if (_st_curr_time) { |
104 | + return _st_curr_time; | ||
105 | + } | ||
106 | + | ||
107 | + return time(NULL); | ||
112 | } | 108 | } |
113 | 109 | ||
114 | - | ||
115 | int st_usleep(st_utime_t usecs) | 110 | int st_usleep(st_utime_t usecs) |
116 | { | 111 | { |
117 | - _st_thread_t *me = _ST_CURRENT_THREAD(); | ||
118 | - | ||
119 | - if (me->flags & _ST_FL_INTERRUPT) { | ||
120 | - me->flags &= ~_ST_FL_INTERRUPT; | ||
121 | - errno = EINTR; | ||
122 | - return -1; | ||
123 | - } | ||
124 | - | ||
125 | - if (usecs != ST_UTIME_NO_TIMEOUT) { | ||
126 | - me->state = _ST_ST_SLEEPING; | ||
127 | - _ST_ADD_SLEEPQ(me, usecs); | ||
128 | - } else | ||
129 | - me->state = _ST_ST_SUSPENDED; | ||
130 | - | ||
131 | - _ST_SWITCH_CONTEXT(me); | ||
132 | - | ||
133 | - if (me->flags & _ST_FL_INTERRUPT) { | ||
134 | - me->flags &= ~_ST_FL_INTERRUPT; | ||
135 | - errno = EINTR; | ||
136 | - return -1; | ||
137 | - } | ||
138 | - | ||
139 | - return 0; | 112 | + _st_thread_t *me = _ST_CURRENT_THREAD(); |
113 | + | ||
114 | + if (me->flags & _ST_FL_INTERRUPT) { | ||
115 | + me->flags &= ~_ST_FL_INTERRUPT; | ||
116 | + errno = EINTR; | ||
117 | + return -1; | ||
118 | + } | ||
119 | + | ||
120 | + if (usecs != ST_UTIME_NO_TIMEOUT) { | ||
121 | + me->state = _ST_ST_SLEEPING; | ||
122 | + _ST_ADD_SLEEPQ(me, usecs); | ||
123 | + } else { | ||
124 | + me->state = _ST_ST_SUSPENDED; | ||
125 | + } | ||
126 | + | ||
127 | + _ST_SWITCH_CONTEXT(me); | ||
128 | + | ||
129 | + if (me->flags & _ST_FL_INTERRUPT) { | ||
130 | + me->flags &= ~_ST_FL_INTERRUPT; | ||
131 | + errno = EINTR; | ||
132 | + return -1; | ||
133 | + } | ||
134 | + | ||
135 | + return 0; | ||
140 | } | 136 | } |
141 | 137 | ||
142 | - | ||
143 | int st_sleep(int secs) | 138 | int st_sleep(int secs) |
144 | { | 139 | { |
145 | - return st_usleep((secs >= 0) ? secs * (st_utime_t) 1000000LL : | ||
146 | - ST_UTIME_NO_TIMEOUT); | 140 | + return st_usleep((secs >= 0) ? secs * (st_utime_t) 1000000LL : ST_UTIME_NO_TIMEOUT); |
147 | } | 141 | } |
148 | 142 | ||
149 | - | ||
150 | /***************************************** | 143 | /***************************************** |
151 | * Condition variable functions | 144 | * Condition variable functions |
152 | */ | 145 | */ |
153 | - | ||
154 | _st_cond_t *st_cond_new(void) | 146 | _st_cond_t *st_cond_new(void) |
155 | { | 147 | { |
156 | - _st_cond_t *cvar; | ||
157 | - | ||
158 | - cvar = (_st_cond_t *) calloc(1, sizeof(_st_cond_t)); | ||
159 | - if (cvar) { | ||
160 | - ST_INIT_CLIST(&cvar->wait_q); | ||
161 | - } | ||
162 | - | ||
163 | - return cvar; | 148 | + _st_cond_t *cvar; |
149 | + | ||
150 | + cvar = (_st_cond_t *) calloc(1, sizeof(_st_cond_t)); | ||
151 | + if (cvar) { | ||
152 | + ST_INIT_CLIST(&cvar->wait_q); | ||
153 | + } | ||
154 | + | ||
155 | + return cvar; | ||
164 | } | 156 | } |
165 | 157 | ||
166 | - | ||
167 | int st_cond_destroy(_st_cond_t *cvar) | 158 | int st_cond_destroy(_st_cond_t *cvar) |
168 | { | 159 | { |
169 | - if (cvar->wait_q.next != &cvar->wait_q) { | ||
170 | - errno = EBUSY; | ||
171 | - return -1; | ||
172 | - } | ||
173 | - | ||
174 | - free(cvar); | ||
175 | - | ||
176 | - return 0; | 160 | + if (cvar->wait_q.next != &cvar->wait_q) { |
161 | + errno = EBUSY; | ||
162 | + return -1; | ||
163 | + } | ||
164 | + | ||
165 | + free(cvar); | ||
166 | + | ||
167 | + return 0; | ||
177 | } | 168 | } |
178 | 169 | ||
179 | - | ||
180 | int st_cond_timedwait(_st_cond_t *cvar, st_utime_t timeout) | 170 | int st_cond_timedwait(_st_cond_t *cvar, st_utime_t timeout) |
181 | { | 171 | { |
182 | - _st_thread_t *me = _ST_CURRENT_THREAD(); | ||
183 | - int rv; | ||
184 | - | ||
185 | - if (me->flags & _ST_FL_INTERRUPT) { | ||
186 | - me->flags &= ~_ST_FL_INTERRUPT; | ||
187 | - errno = EINTR; | ||
188 | - return -1; | ||
189 | - } | ||
190 | - | ||
191 | - /* Put caller thread on the condition variable's wait queue */ | ||
192 | - me->state = _ST_ST_COND_WAIT; | ||
193 | - ST_APPEND_LINK(&me->wait_links, &cvar->wait_q); | ||
194 | - | ||
195 | - if (timeout != ST_UTIME_NO_TIMEOUT) | ||
196 | - _ST_ADD_SLEEPQ(me, timeout); | ||
197 | - | ||
198 | - _ST_SWITCH_CONTEXT(me); | ||
199 | - | ||
200 | - ST_REMOVE_LINK(&me->wait_links); | ||
201 | - rv = 0; | ||
202 | - | ||
203 | - if (me->flags & _ST_FL_TIMEDOUT) { | ||
204 | - me->flags &= ~_ST_FL_TIMEDOUT; | ||
205 | - errno = ETIME; | ||
206 | - rv = -1; | ||
207 | - } | ||
208 | - if (me->flags & _ST_FL_INTERRUPT) { | ||
209 | - me->flags &= ~_ST_FL_INTERRUPT; | ||
210 | - errno = EINTR; | ||
211 | - rv = -1; | ||
212 | - } | ||
213 | - | ||
214 | - return rv; | 172 | + _st_thread_t *me = _ST_CURRENT_THREAD(); |
173 | + int rv; | ||
174 | + | ||
175 | + if (me->flags & _ST_FL_INTERRUPT) { | ||
176 | + me->flags &= ~_ST_FL_INTERRUPT; | ||
177 | + errno = EINTR; | ||
178 | + return -1; | ||
179 | + } | ||
180 | + | ||
181 | + /* Put caller thread on the condition variable's wait queue */ | ||
182 | + me->state = _ST_ST_COND_WAIT; | ||
183 | + ST_APPEND_LINK(&me->wait_links, &cvar->wait_q); | ||
184 | + | ||
185 | + if (timeout != ST_UTIME_NO_TIMEOUT) { | ||
186 | + _ST_ADD_SLEEPQ(me, timeout); | ||
187 | + } | ||
188 | + | ||
189 | + _ST_SWITCH_CONTEXT(me); | ||
190 | + | ||
191 | + ST_REMOVE_LINK(&me->wait_links); | ||
192 | + rv = 0; | ||
193 | + | ||
194 | + if (me->flags & _ST_FL_TIMEDOUT) { | ||
195 | + me->flags &= ~_ST_FL_TIMEDOUT; | ||
196 | + errno = ETIME; | ||
197 | + rv = -1; | ||
198 | + } | ||
199 | + if (me->flags & _ST_FL_INTERRUPT) { | ||
200 | + me->flags &= ~_ST_FL_INTERRUPT; | ||
201 | + errno = EINTR; | ||
202 | + rv = -1; | ||
203 | + } | ||
204 | + | ||
205 | + return rv; | ||
215 | } | 206 | } |
216 | 207 | ||
217 | - | ||
218 | int st_cond_wait(_st_cond_t *cvar) | 208 | int st_cond_wait(_st_cond_t *cvar) |
219 | { | 209 | { |
220 | - return st_cond_timedwait(cvar, ST_UTIME_NO_TIMEOUT); | 210 | + return st_cond_timedwait(cvar, ST_UTIME_NO_TIMEOUT); |
221 | } | 211 | } |
222 | 212 | ||
223 | - | ||
224 | static int _st_cond_signal(_st_cond_t *cvar, int broadcast) | 213 | static int _st_cond_signal(_st_cond_t *cvar, int broadcast) |
225 | { | 214 | { |
226 | - _st_thread_t *thread; | ||
227 | - _st_clist_t *q; | ||
228 | - | ||
229 | - for (q = cvar->wait_q.next; q != &cvar->wait_q; q = q->next) { | ||
230 | - thread = _ST_THREAD_WAITQ_PTR(q); | ||
231 | - if (thread->state == _ST_ST_COND_WAIT) { | ||
232 | - if (thread->flags & _ST_FL_ON_SLEEPQ) | ||
233 | - _ST_DEL_SLEEPQ(thread); | ||
234 | - | ||
235 | - /* Make thread runnable */ | ||
236 | - thread->state = _ST_ST_RUNNABLE; | ||
237 | - _ST_ADD_RUNQ(thread); | ||
238 | - if (!broadcast) | ||
239 | - break; | 215 | + _st_thread_t *thread; |
216 | + _st_clist_t *q; | ||
217 | + | ||
218 | + for (q = cvar->wait_q.next; q != &cvar->wait_q; q = q->next) { | ||
219 | + thread = _ST_THREAD_WAITQ_PTR(q); | ||
220 | + if (thread->state == _ST_ST_COND_WAIT) { | ||
221 | + if (thread->flags & _ST_FL_ON_SLEEPQ) { | ||
222 | + _ST_DEL_SLEEPQ(thread); | ||
223 | + } | ||
224 | + | ||
225 | + /* Make thread runnable */ | ||
226 | + thread->state = _ST_ST_RUNNABLE; | ||
227 | + _ST_ADD_RUNQ(thread); | ||
228 | + if (!broadcast) { | ||
229 | + break; | ||
230 | + } | ||
231 | + } | ||
240 | } | 232 | } |
241 | - } | ||
242 | - | ||
243 | - return 0; | 233 | + |
234 | + return 0; | ||
244 | } | 235 | } |
245 | 236 | ||
246 | - | ||
247 | int st_cond_signal(_st_cond_t *cvar) | 237 | int st_cond_signal(_st_cond_t *cvar) |
248 | { | 238 | { |
249 | - return _st_cond_signal(cvar, 0); | 239 | + return _st_cond_signal(cvar, 0); |
250 | } | 240 | } |
251 | 241 | ||
252 | - | ||
253 | int st_cond_broadcast(_st_cond_t *cvar) | 242 | int st_cond_broadcast(_st_cond_t *cvar) |
254 | { | 243 | { |
255 | - return _st_cond_signal(cvar, 1); | 244 | + return _st_cond_signal(cvar, 1); |
256 | } | 245 | } |
257 | 246 | ||
258 | - | ||
259 | /***************************************** | 247 | /***************************************** |
260 | * Mutex functions | 248 | * Mutex functions |
261 | */ | 249 | */ |
262 | - | ||
263 | _st_mutex_t *st_mutex_new(void) | 250 | _st_mutex_t *st_mutex_new(void) |
264 | { | 251 | { |
265 | - _st_mutex_t *lock; | ||
266 | - | ||
267 | - lock = (_st_mutex_t *) calloc(1, sizeof(_st_mutex_t)); | ||
268 | - if (lock) { | ||
269 | - ST_INIT_CLIST(&lock->wait_q); | ||
270 | - lock->owner = NULL; | ||
271 | - } | ||
272 | - | ||
273 | - return lock; | 252 | + _st_mutex_t *lock; |
253 | + | ||
254 | + lock = (_st_mutex_t *) calloc(1, sizeof(_st_mutex_t)); | ||
255 | + if (lock) { | ||
256 | + ST_INIT_CLIST(&lock->wait_q); | ||
257 | + lock->owner = NULL; | ||
258 | + } | ||
259 | + | ||
260 | + return lock; | ||
274 | } | 261 | } |
275 | 262 | ||
276 | - | ||
277 | int st_mutex_destroy(_st_mutex_t *lock) | 263 | int st_mutex_destroy(_st_mutex_t *lock) |
278 | { | 264 | { |
279 | - if (lock->owner != NULL || lock->wait_q.next != &lock->wait_q) { | ||
280 | - errno = EBUSY; | ||
281 | - return -1; | ||
282 | - } | ||
283 | - | ||
284 | - free(lock); | ||
285 | - | ||
286 | - return 0; | 265 | + if (lock->owner != NULL || lock->wait_q.next != &lock->wait_q) { |
266 | + errno = EBUSY; | ||
267 | + return -1; | ||
268 | + } | ||
269 | + | ||
270 | + free(lock); | ||
271 | + | ||
272 | + return 0; | ||
287 | } | 273 | } |
288 | 274 | ||
289 | - | ||
290 | int st_mutex_lock(_st_mutex_t *lock) | 275 | int st_mutex_lock(_st_mutex_t *lock) |
291 | { | 276 | { |
292 | - _st_thread_t *me = _ST_CURRENT_THREAD(); | ||
293 | - | ||
294 | - if (me->flags & _ST_FL_INTERRUPT) { | ||
295 | - me->flags &= ~_ST_FL_INTERRUPT; | ||
296 | - errno = EINTR; | ||
297 | - return -1; | ||
298 | - } | ||
299 | - | ||
300 | - if (lock->owner == NULL) { | ||
301 | - /* Got the mutex */ | ||
302 | - lock->owner = me; | 277 | + _st_thread_t *me = _ST_CURRENT_THREAD(); |
278 | + | ||
279 | + if (me->flags & _ST_FL_INTERRUPT) { | ||
280 | + me->flags &= ~_ST_FL_INTERRUPT; | ||
281 | + errno = EINTR; | ||
282 | + return -1; | ||
283 | + } | ||
284 | + | ||
285 | + if (lock->owner == NULL) { | ||
286 | + /* Got the mutex */ | ||
287 | + lock->owner = me; | ||
288 | + return 0; | ||
289 | + } | ||
290 | + | ||
291 | + if (lock->owner == me) { | ||
292 | + errno = EDEADLK; | ||
293 | + return -1; | ||
294 | + } | ||
295 | + | ||
296 | + /* Put caller thread on the mutex's wait queue */ | ||
297 | + me->state = _ST_ST_LOCK_WAIT; | ||
298 | + ST_APPEND_LINK(&me->wait_links, &lock->wait_q); | ||
299 | + | ||
300 | + _ST_SWITCH_CONTEXT(me); | ||
301 | + | ||
302 | + ST_REMOVE_LINK(&me->wait_links); | ||
303 | + | ||
304 | + if ((me->flags & _ST_FL_INTERRUPT) && lock->owner != me) { | ||
305 | + me->flags &= ~_ST_FL_INTERRUPT; | ||
306 | + errno = EINTR; | ||
307 | + return -1; | ||
308 | + } | ||
309 | + | ||
303 | return 0; | 310 | return 0; |
304 | - } | ||
305 | - | ||
306 | - if (lock->owner == me) { | ||
307 | - errno = EDEADLK; | ||
308 | - return -1; | ||
309 | - } | ||
310 | - | ||
311 | - /* Put caller thread on the mutex's wait queue */ | ||
312 | - me->state = _ST_ST_LOCK_WAIT; | ||
313 | - ST_APPEND_LINK(&me->wait_links, &lock->wait_q); | ||
314 | - | ||
315 | - _ST_SWITCH_CONTEXT(me); | ||
316 | - | ||
317 | - ST_REMOVE_LINK(&me->wait_links); | ||
318 | - | ||
319 | - if ((me->flags & _ST_FL_INTERRUPT) && lock->owner != me) { | ||
320 | - me->flags &= ~_ST_FL_INTERRUPT; | ||
321 | - errno = EINTR; | ||
322 | - return -1; | ||
323 | - } | ||
324 | - | ||
325 | - return 0; | ||
326 | } | 311 | } |
327 | 312 | ||
328 | - | ||
329 | int st_mutex_unlock(_st_mutex_t *lock) | 313 | int st_mutex_unlock(_st_mutex_t *lock) |
330 | { | 314 | { |
331 | - _st_thread_t *thread; | ||
332 | - _st_clist_t *q; | ||
333 | - | ||
334 | - if (lock->owner != _ST_CURRENT_THREAD()) { | ||
335 | - errno = EPERM; | ||
336 | - return -1; | ||
337 | - } | ||
338 | - | ||
339 | - for (q = lock->wait_q.next; q != &lock->wait_q; q = q->next) { | ||
340 | - thread = _ST_THREAD_WAITQ_PTR(q); | ||
341 | - if (thread->state == _ST_ST_LOCK_WAIT) { | ||
342 | - lock->owner = thread; | ||
343 | - /* Make thread runnable */ | ||
344 | - thread->state = _ST_ST_RUNNABLE; | ||
345 | - _ST_ADD_RUNQ(thread); | ||
346 | - return 0; | 315 | + _st_thread_t *thread; |
316 | + _st_clist_t *q; | ||
317 | + | ||
318 | + if (lock->owner != _ST_CURRENT_THREAD()) { | ||
319 | + errno = EPERM; | ||
320 | + return -1; | ||
347 | } | 321 | } |
348 | - } | ||
349 | - | ||
350 | - /* No threads waiting on this mutex */ | ||
351 | - lock->owner = NULL; | ||
352 | - | ||
353 | - return 0; | 322 | + |
323 | + for (q = lock->wait_q.next; q != &lock->wait_q; q = q->next) { | ||
324 | + thread = _ST_THREAD_WAITQ_PTR(q); | ||
325 | + if (thread->state == _ST_ST_LOCK_WAIT) { | ||
326 | + lock->owner = thread; | ||
327 | + /* Make thread runnable */ | ||
328 | + thread->state = _ST_ST_RUNNABLE; | ||
329 | + _ST_ADD_RUNQ(thread); | ||
330 | + return 0; | ||
331 | + } | ||
332 | + } | ||
333 | + | ||
334 | + /* No threads waiting on this mutex */ | ||
335 | + lock->owner = NULL; | ||
336 | + | ||
337 | + return 0; | ||
354 | } | 338 | } |
355 | 339 | ||
356 | - | ||
357 | int st_mutex_trylock(_st_mutex_t *lock) | 340 | int st_mutex_trylock(_st_mutex_t *lock) |
358 | { | 341 | { |
359 | - if (lock->owner != NULL) { | ||
360 | - errno = EBUSY; | ||
361 | - return -1; | ||
362 | - } | ||
363 | - | ||
364 | - /* Got the mutex */ | ||
365 | - lock->owner = _ST_CURRENT_THREAD(); | ||
366 | - | ||
367 | - return 0; | 342 | + if (lock->owner != NULL) { |
343 | + errno = EBUSY; | ||
344 | + return -1; | ||
345 | + } | ||
346 | + | ||
347 | + /* Got the mutex */ | ||
348 | + lock->owner = _ST_CURRENT_THREAD(); | ||
349 | + | ||
350 | + return 0; | ||
368 | } | 351 | } |
369 | 352 |
-
请 注册 或 登录 后发表评论