|
1 /* |
|
2 * $Id: thread-st.h$ |
|
3 * pthread version |
|
4 * by Wolfram Gloger 2004 |
|
5 */ |
|
6 |
|
7 #include <pthread.h> |
|
8 #include <stdio.h> |
|
9 |
|
10 pthread_cond_t finish_cond = PTHREAD_COND_INITIALIZER; |
|
11 pthread_mutex_t finish_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
12 |
|
13 #ifndef USE_PTHREADS_STACKS |
|
14 #define USE_PTHREADS_STACKS 0 |
|
15 #endif |
|
16 |
|
17 #ifndef STACKSIZE |
|
18 #define STACKSIZE 32768 |
|
19 #endif |
|
20 |
|
21 struct thread_st { |
|
22 char *sp; /* stack pointer, can be 0 */ |
|
23 void (*func)(struct thread_st* st); /* must be set by user */ |
|
24 pthread_t id; |
|
25 int flags; |
|
26 struct user_data u; |
|
27 }; |
|
28 |
|
29 static void |
|
30 thread_init(void) |
|
31 { |
|
32 printf("Using posix threads.\n"); |
|
33 pthread_cond_init(&finish_cond, NULL); |
|
34 pthread_mutex_init(&finish_mutex, NULL); |
|
35 } |
|
36 |
|
37 static void * |
|
38 thread_wrapper(void *ptr) |
|
39 { |
|
40 struct thread_st *st = (struct thread_st*)ptr; |
|
41 |
|
42 /*printf("begin %p\n", st->sp);*/ |
|
43 st->func(st); |
|
44 pthread_mutex_lock(&finish_mutex); |
|
45 st->flags = 1; |
|
46 pthread_mutex_unlock(&finish_mutex); |
|
47 pthread_cond_signal(&finish_cond); |
|
48 /*printf("end %p\n", st->sp);*/ |
|
49 return NULL; |
|
50 } |
|
51 |
|
52 /* Create a thread. */ |
|
53 static int |
|
54 thread_create(struct thread_st *st) |
|
55 { |
|
56 st->flags = 0; |
|
57 { |
|
58 pthread_attr_t* attr_p = 0; |
|
59 #if USE_PTHREADS_STACKS |
|
60 pthread_attr_t attr; |
|
61 |
|
62 pthread_attr_init (&attr); |
|
63 if(!st->sp) |
|
64 st->sp = malloc(STACKSIZE+16); |
|
65 if(!st->sp) |
|
66 return -1; |
|
67 if(pthread_attr_setstacksize(&attr, STACKSIZE)) |
|
68 fprintf(stderr, "error setting stacksize"); |
|
69 else |
|
70 pthread_attr_setstackaddr(&attr, st->sp + STACKSIZE); |
|
71 /*printf("create %p\n", st->sp);*/ |
|
72 attr_p = &attr; |
|
73 #endif |
|
74 return pthread_create(&st->id, attr_p, thread_wrapper, st); |
|
75 } |
|
76 return 0; |
|
77 } |
|
78 |
|
79 /* Wait for one of several subthreads to finish. */ |
|
80 static void |
|
81 wait_for_thread(struct thread_st st[], int n_thr, |
|
82 int (*end_thr)(struct thread_st*)) |
|
83 { |
|
84 int i; |
|
85 |
|
86 pthread_mutex_lock(&finish_mutex); |
|
87 for(;;) { |
|
88 int term = 0; |
|
89 for(i=0; i<n_thr; i++) |
|
90 if(st[i].flags) { |
|
91 /*printf("joining %p\n", st[i].sp);*/ |
|
92 if(pthread_join(st[i].id, NULL) == 0) { |
|
93 st[i].flags = 0; |
|
94 if(end_thr) |
|
95 end_thr(&st[i]); |
|
96 } else |
|
97 fprintf(stderr, "can't join\n"); |
|
98 ++term; |
|
99 } |
|
100 if(term > 0) |
|
101 break; |
|
102 pthread_cond_wait(&finish_cond, &finish_mutex); |
|
103 } |
|
104 pthread_mutex_unlock(&finish_mutex); |
|
105 } |
|
106 |
|
107 /* |
|
108 * Local variables: |
|
109 * tab-width: 4 |
|
110 * End: |
|
111 */ |