|
1 /* |
|
2 * $Id:$ |
|
3 * sproc version |
|
4 * by Wolfram Gloger 2001, 2004, 2006 |
|
5 */ |
|
6 |
|
7 #include <stdio.h> |
|
8 #include <sys/wait.h> |
|
9 #include <sys/types.h> |
|
10 #include <sys/prctl.h> |
|
11 |
|
12 #ifndef STACKSIZE |
|
13 #define STACKSIZE 32768 |
|
14 #endif |
|
15 |
|
16 struct thread_st { |
|
17 char *sp; /* stack pointer, can be 0 */ |
|
18 void (*func)(struct thread_st* st); /* must be set by user */ |
|
19 int id; |
|
20 int flags; |
|
21 struct user_data u; |
|
22 }; |
|
23 |
|
24 static void |
|
25 thread_init(void) |
|
26 { |
|
27 printf("Using sproc() threads.\n"); |
|
28 } |
|
29 |
|
30 static void |
|
31 thread_wrapper(void *ptr, size_t stack_len) |
|
32 { |
|
33 struct thread_st *st = (struct thread_st*)ptr; |
|
34 |
|
35 /*printf("begin %p\n", st->sp);*/ |
|
36 st->func(st); |
|
37 /*printf("end %p\n", st->sp);*/ |
|
38 } |
|
39 |
|
40 /* Create a thread. */ |
|
41 static int |
|
42 thread_create(struct thread_st *st) |
|
43 { |
|
44 st->flags = 0; |
|
45 if(!st->sp) |
|
46 st->sp = malloc(STACKSIZE); |
|
47 if(!st->sp) return -1; |
|
48 st->id = sprocsp(thread_wrapper, PR_SALL, st, st->sp+STACKSIZE, STACKSIZE); |
|
49 if(st->id < 0) { |
|
50 return -1; |
|
51 } |
|
52 return 0; |
|
53 } |
|
54 |
|
55 /* Wait for one of several subthreads to finish. */ |
|
56 static void |
|
57 wait_for_thread(struct thread_st st[], int n_thr, |
|
58 int (*end_thr)(struct thread_st*)) |
|
59 { |
|
60 int i; |
|
61 int id; |
|
62 |
|
63 int status = 0; |
|
64 id = wait(&status); |
|
65 if(status != 0) { |
|
66 if(WIFSIGNALED(status)) |
|
67 printf("thread %id terminated by signal %d\n", |
|
68 id, WTERMSIG(status)); |
|
69 else |
|
70 printf("thread %id exited with status %d\n", |
|
71 id, WEXITSTATUS(status)); |
|
72 } |
|
73 for(i=0; i<n_thr; i++) |
|
74 if(id == st[i].id) { |
|
75 if(end_thr) |
|
76 end_thr(&st[i]); |
|
77 break; |
|
78 } |
|
79 } |
|
80 |
|
81 /* |
|
82 * Local variables: |
|
83 * tab-width: 4 |
|
84 * End: |
|
85 */ |