modules/th/thread.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- TH_acquire_read_lock
- TH_release_read_lock
- TH_acquire_write_lock
- TH_release_write_lock
- TH_init_read_write_lock
- TH_acquire_read_lockw
- TH_release_read_lockw
- TH_acquire_write_lockw
- TH_release_write_lockw
- TH_init_read_write_lockw
- TH_get_id
- TH_to_string
- TH_create
1 /***************************************
2 $Revision: 1.28 $
3
4 Example code: A thread.
5
6 Status: NOT REVUED, NOT TESTED
7
8 Authors: Chris Ottrey
9 Joao Damas
10
11 +html+ <DL COMPACT>
12 +html+ <DT>Online References:
13 +html+ <DD><UL>
14 +html+ </UL>
15 +html+ </DL>
16
17 ******************/ /******************
18 Modification History:
19 ottrey (02/03/1999) Created.
20 ottrey (08/03/1999) Modified.
21 ottrey (17/06/1999) Stripped down.
22 joao (22/06/1999) Redid thread startup
23 ******************/ /******************
24 Copyright (c) 1999,2000,2001 RIPE NCC
25
26 All Rights Reserved
27
28 Permission to use, copy, modify, and distribute this software and its
29 documentation for any purpose and without fee is hereby granted,
30 provided that the above copyright notice appear in all copies and that
31 both that copyright notice and this permission notice appear in
32 supporting documentation, and that the name of the author not be
33 used in advertising or publicity pertaining to distribution of the
34 software without specific, written prior permission.
35
36 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
37 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
38 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
39 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
40 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
41 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 ***************************************/
43
44 #include "rip.h"
45
46 #include <pthread.h> /* Posix thread library */
47 #include <stdio.h>
48 #include <strings.h>
49
50 //typedef struct th_args {
51 // void *function;
52 // int sock;
53 //} th_args;
54
55 /*************************************************
56 * *
57 * Readers Writes Locks that favor READERS *
58 * *
59 *************************************************/
60 /* TH_acquire_read_lock() */
61 /*++++++++++++++++++++++++++++++++++++++
62
63 Aquire a readers lock.
64
65 rw_lock_t *prw_lock Readers writers lock.
66
67 Reference: "Multithreaded Programming Techniques - Prasad p.192"
68 More:
69 +html+ <PRE>
70 Author:
71 ottrey
72 +html+ </PRE>
73 ++++++++++++++++++++++++++++++++++++++*/
74 void TH_acquire_read_lock(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
75 pthread_mutex_lock(&prw_lock->rw_mutex);
76
77 while (prw_lock->rw_count < 0) {
78 pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
79 }
80
81 ++prw_lock->rw_count;
82 pthread_mutex_unlock(&prw_lock->rw_mutex);
83
84 } /* TH_acquire_read_lock() */
85
86 /* TH_release_read_lock() */
87 /*++++++++++++++++++++++++++++++++++++++
88
89 Release a readers lock.
90
91 rw_lock_t *prw_lock Readers writers lock.
92
93 Reference: "Multithreaded Programming Techniques - Prasad p.192"
94 More:
95 +html+ <PRE>
96 Author:
97 ottrey
98 +html+ </PRE>
99 ++++++++++++++++++++++++++++++++++++++*/
100 void TH_release_read_lock(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
101 pthread_mutex_lock(&prw_lock->rw_mutex);
102
103 --prw_lock->rw_count;
104
105 if (!prw_lock->rw_count) {
106 pthread_cond_signal(&prw_lock->rw_cond);
107 }
108
109 pthread_mutex_unlock(&prw_lock->rw_mutex);
110
111 } /* TH_release_read_lock() */
112
113 /* TH_acquire_write_lock() */
114 /*++++++++++++++++++++++++++++++++++++++
115
116 Aquire a writers lock.
117
118 rw_lock_t *prw_lock Readers writers lock.
119
120 Reference: "Multithreaded Programming Techniques - Prasad p.192"
121 More:
122 +html+ <PRE>
123 Author:
124 ottrey
125 +html+ </PRE>
126 ++++++++++++++++++++++++++++++++++++++*/
127 void TH_acquire_write_lock(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
128 pthread_mutex_lock(&prw_lock->rw_mutex);
129
130 while (prw_lock->rw_count != 0) {
131 pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
132 }
133
134 prw_lock->rw_count = -1;
135 pthread_mutex_unlock(&prw_lock->rw_mutex);
136
137 } /* TH_acquire_write_lock() */
138
139 /* TH_release_write_lock() */
140 /*++++++++++++++++++++++++++++++++++++++
141
142 Release a writers lock.
143
144 rw_lock_t *prw_lock Readers writers lock.
145
146 Reference: "Multithreaded Programming Techniques - Prasad p.192"
147 More:
148 +html+ <PRE>
149 Author:
150 ottrey
151 +html+ </PRE>
152 ++++++++++++++++++++++++++++++++++++++*/
153 void TH_release_write_lock(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
154 pthread_mutex_lock(&prw_lock->rw_mutex);
155 prw_lock->rw_count = 0;
156 pthread_mutex_unlock(&prw_lock->rw_mutex);
157 pthread_cond_broadcast(&prw_lock->rw_cond);
158
159 } /* TH_release_write_lock() */
160
161 /* TH_init_read_write_lock() */
162 /*++++++++++++++++++++++++++++++++++++++
163
164 Initialize a readers/writers lock.
165
166 rw_lock_t *prw_lock Readers writers lock.
167
168 Side effect: the lock is set to open(?)
169
170 Reference: "Multithreaded Programming Techniques - Prasad p.192"
171 More:
172 +html+ <PRE>
173 Author:
174 ottrey
175 +html+ </PRE>
176 ++++++++++++++++++++++++++++++++++++++*/
177 void TH_init_read_write_lock(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
178 pthread_mutex_init(&prw_lock->rw_mutex, NULL);
179 pthread_cond_init(&prw_lock->rw_cond, NULL);
180 pthread_cond_init(&prw_lock->w_cond, NULL);
181 prw_lock->rw_count = 0;
182 prw_lock->w_count = 1; /* just in case one uses wrong interface */
183
184 } /* TH_init_read_write_lock() */
185
186 /*************************************************
187 * *
188 * Readers Writes Locks that favor WRITERS *
189 * *
190 *************************************************/
191 /* TH_acquire_read_lockw() */
192 /*++++++++++++++++++++++++++++++++++++++
193
194 Aquire a readers lock.
195
196 rw_lock_t *prw_lock Readers writers lock.
197
198 Reference: "Multithreaded Programming Techniques - Prasad p.192"
199 More:
200 +html+ <PRE>
201 Author:
202 ottrey
203 +html+ </PRE>
204 ++++++++++++++++++++++++++++++++++++++*/
205 void TH_acquire_read_lockw(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
206 pthread_mutex_lock(&prw_lock->rw_mutex);
207
208 while (prw_lock->w_count != 0) {
209 pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
210 }
211
212 ++prw_lock->rw_count;
213 pthread_mutex_unlock(&prw_lock->rw_mutex);
214
215 } /* TH_acquire_read_lockw() */
216
217 /* TH_release_read_lockw() */
218 /*++++++++++++++++++++++++++++++++++++++
219
220 Release a readers lock.
221
222 rw_lock_t *prw_lock Readers writers lock.
223
224 Reference: "Multithreaded Programming Techniques - Prasad p.192"
225 More:
226 +html+ <PRE>
227 Author:
228 ottrey
229 +html+ </PRE>
230 ++++++++++++++++++++++++++++++++++++++*/
231 void TH_release_read_lockw(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
232 pthread_mutex_lock(&prw_lock->rw_mutex);
233
234 --prw_lock->rw_count;
235
236 if (!prw_lock->rw_count) {
237 pthread_cond_signal(&prw_lock->rw_cond);
238 }
239
240 pthread_mutex_unlock(&prw_lock->rw_mutex);
241
242 } /* TH_release_read_lockw() */
243
244 /* TH_acquire_write_lockw() */
245 /*++++++++++++++++++++++++++++++++++++++
246
247 Aquire a writers lock.
248
249 rw_lock_t *prw_lock Readers writers lock.
250
251 Reference: "Multithreaded Programming Techniques - Prasad p.192"
252 More:
253 +html+ <PRE>
254 Author:
255 ottrey
256 +html+ </PRE>
257 ++++++++++++++++++++++++++++++++++++++*/
258 void TH_acquire_write_lockw(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
259 pthread_mutex_lock(&prw_lock->rw_mutex);
260
261 /* check for writers */
262 while (prw_lock->w_count != 0) {
263 pthread_cond_wait(&prw_lock->w_cond, &prw_lock->rw_mutex);
264 }
265
266 prw_lock->w_count = 1;
267
268 /* wait until all readers are gone */
269 while (prw_lock->rw_count != 0) {
270 pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
271 }
272
273 pthread_mutex_unlock(&prw_lock->rw_mutex);
274
275 } /* TH_acquire_write_lockw() */
276
277 /* TH_release_write_lockw() */
278 /*++++++++++++++++++++++++++++++++++++++
279
280 Release a writers lock.
281
282 rw_lock_t *prw_lock Readers writers lock.
283
284 Reference: "Multithreaded Programming Techniques - Prasad p.192"
285 More:
286 +html+ <PRE>
287 Author:
288 ottrey
289 +html+ </PRE>
290 ++++++++++++++++++++++++++++++++++++++*/
291 void TH_release_write_lockw(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
292 pthread_mutex_lock(&prw_lock->rw_mutex);
293 prw_lock->w_count = 0;
294 pthread_mutex_unlock(&prw_lock->rw_mutex);
295 pthread_cond_broadcast(&prw_lock->w_cond);
296
297 } /* TH_release_write_lockw() */
298
299 /* TH_init_read_write_lockw() */
300 /*++++++++++++++++++++++++++++++++++++++
301
302 Initialize a readers/writers lock.
303
304 rw_lock_t *prw_lock Readers writers lock.
305
306 Side effect: the lock is set to open(?)
307
308 Reference: "Multithreaded Programming Techniques - Prasad p.192"
309 More:
310 +html+ <PRE>
311 Author:
312 ottrey
313 +html+ </PRE>
314 ++++++++++++++++++++++++++++++++++++++*/
315 void TH_init_read_write_lockw(rw_lock_t *prw_lock) {
/* [<][>][^][v][top][bottom][index][help] */
316 pthread_mutex_init(&prw_lock->rw_mutex, NULL);
317 pthread_cond_init(&prw_lock->rw_cond, NULL);
318 pthread_cond_init(&prw_lock->w_cond, NULL);
319 prw_lock->rw_count = 0;
320 prw_lock->w_count = 0;
321
322 } /* TH_init_read_write_lockw() */
323
324
325
326 /*************************************************
327 * *
328 * Other functions *
329 * *
330 *************************************************/
331
332
333 int TH_get_id(void) {
/* [<][>][^][v][top][bottom][index][help] */
334
335 return (int)pthread_self();
336
337 } /* TH_get_id() */
338
339 /* TH_to_string() */
340 char *TH_to_string(void) {
/* [<][>][^][v][top][bottom][index][help] */
341 char tmp[STR_L];
342 char thread_info_buffer[STR_XL];
343
344 strcpy(thread_info_buffer, "Thread = { ");
345
346 sprintf(tmp, "[pthread_self] = \"%lu\" ", (long unsigned)pthread_self());
347 strcat(thread_info_buffer, tmp);
348
349 /*
350 thread_name = (char *)pthread_getspecific(Name);
351
352 if (thread_name == NULL ) {
353 sprintf(tmp, "[Name] = \"%s\" ", "didn't work!");
354 }
355 else {
356 sprintf(tmp, "[Name] = \"%s\" ", thread_name);
357 }
358 strcat(thread_info_buffer, tmp);
359 */
360
361 strcat(thread_info_buffer, "}");
362
363 return UT_strdup(thread_info_buffer);
364 } /* TH_to_string() */
365
366
367 /*++++++++++++++++++++++++++++++++++++++
368
369 This is the routine that creates a thread.
370
371 More:
372 +html+ <PRE>
373 Author:
374 ottrey
375 joao
376 andrei
377 +html+ </PRE>
378 ++++++++++++++++++++++++++++++++++++++*/
379 pthread_t TH_create(void *do_function(void *), void *arguments ) {
/* [<][>][^][v][top][bottom][index][help] */
380 pthread_t tid;
381 pthread_attr_t attr;
382 size_t ssize;
383 int ret;
384
385 /* Start a new thread. */
386 pthread_attr_init(&attr); /* initialize attr with default attributes */
387 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
388
389 #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
390 defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
391 /*********
392 For SCO, we need to increase the stack size, because the default is
393 exceedingly small. This also works on FreeBSD. In Solaris, the
394 stack size is 0, which is interpreted as the default, meaning 1
395 Mbyte for 32-bit processes or 2 Mbyte for 64-bit processes.
396 However, trying to *set* the stack size to 0 results in an error.
397 Therefore, we don't want to set the size to 0. Probably not a good
398 idea in any event. :) Linux doesn't support this function (as of
399 the 2.4.2 kernel).
400
401 Note: see also modules/sk/cd_watchdog.c
402 *********/
403 dieif(pthread_attr_getstacksize(&attr, &ssize) != 0);
404 if (ssize > 0) {
405 dieif(pthread_attr_setstacksize(&attr, ssize * 4) != 0);
406 }
407 #endif
408
409 ret = pthread_create(&tid, &attr, do_function, arguments);
410 if( ret !=0 ) die;
411 pthread_attr_destroy(&attr);
412
413 return tid;
414
415 } /* TH_run() */
416
417
418