|
1 |
|
2 #include <stdlib.h> |
|
3 #include <lwp/lwp.h> |
|
4 #include <lwp/stackdep.h> |
|
5 |
|
6 #define STACKSIZE 1000 /* stacksize for a thread */ |
|
7 #define NSTACKS 2 /* # stacks to be put in cache initially */ |
|
8 |
|
9 struct lock { |
|
10 int lock_locked; |
|
11 cv_t lock_condvar; |
|
12 mon_t lock_monitor; |
|
13 }; |
|
14 |
|
15 |
|
16 /* |
|
17 * Initialization. |
|
18 */ |
|
19 static void PyThread__init_thread(void) |
|
20 { |
|
21 lwp_setstkcache(STACKSIZE, NSTACKS); |
|
22 } |
|
23 |
|
24 /* |
|
25 * Thread support. |
|
26 */ |
|
27 |
|
28 |
|
29 long PyThread_start_new_thread(void (*func)(void *), void *arg) |
|
30 { |
|
31 thread_t tid; |
|
32 int success; |
|
33 dprintf(("PyThread_start_new_thread called\n")); |
|
34 if (!initialized) |
|
35 PyThread_init_thread(); |
|
36 success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg); |
|
37 return success < 0 ? -1 : 0; |
|
38 } |
|
39 |
|
40 long PyThread_get_thread_ident(void) |
|
41 { |
|
42 thread_t tid; |
|
43 if (!initialized) |
|
44 PyThread_init_thread(); |
|
45 if (lwp_self(&tid) < 0) |
|
46 return -1; |
|
47 return tid.thread_id; |
|
48 } |
|
49 |
|
50 static void do_PyThread_exit_thread(int no_cleanup) |
|
51 { |
|
52 dprintf(("PyThread_exit_thread called\n")); |
|
53 if (!initialized) |
|
54 if (no_cleanup) |
|
55 _exit(0); |
|
56 else |
|
57 exit(0); |
|
58 lwp_destroy(SELF); |
|
59 } |
|
60 |
|
61 void PyThread_exit_thread(void) |
|
62 { |
|
63 do_PyThread_exit_thread(0); |
|
64 } |
|
65 |
|
66 void PyThread__exit_thread(void) |
|
67 { |
|
68 do_PyThread_exit_thread(1); |
|
69 } |
|
70 |
|
71 #ifndef NO_EXIT_PROG |
|
72 static void do_PyThread_exit_prog(int status, int no_cleanup) |
|
73 { |
|
74 dprintf(("PyThread_exit_prog(%d) called\n", status)); |
|
75 if (!initialized) |
|
76 if (no_cleanup) |
|
77 _exit(status); |
|
78 else |
|
79 exit(status); |
|
80 pod_exit(status); |
|
81 } |
|
82 |
|
83 void PyThread_exit_prog(int status) |
|
84 { |
|
85 do_PyThread_exit_prog(status, 0); |
|
86 } |
|
87 |
|
88 void PyThread__exit_prog(int status) |
|
89 { |
|
90 do_PyThread_exit_prog(status, 1); |
|
91 } |
|
92 #endif /* NO_EXIT_PROG */ |
|
93 |
|
94 /* |
|
95 * Lock support. |
|
96 */ |
|
97 PyThread_type_lock PyThread_allocate_lock(void) |
|
98 { |
|
99 struct lock *lock; |
|
100 extern char *malloc(size_t); |
|
101 |
|
102 dprintf(("PyThread_allocate_lock called\n")); |
|
103 if (!initialized) |
|
104 PyThread_init_thread(); |
|
105 |
|
106 lock = (struct lock *) malloc(sizeof(struct lock)); |
|
107 lock->lock_locked = 0; |
|
108 (void) mon_create(&lock->lock_monitor); |
|
109 (void) cv_create(&lock->lock_condvar, lock->lock_monitor); |
|
110 dprintf(("PyThread_allocate_lock() -> %p\n", lock)); |
|
111 return (PyThread_type_lock) lock; |
|
112 } |
|
113 |
|
114 void PyThread_free_lock(PyThread_type_lock lock) |
|
115 { |
|
116 dprintf(("PyThread_free_lock(%p) called\n", lock)); |
|
117 mon_destroy(((struct lock *) lock)->lock_monitor); |
|
118 free((char *) lock); |
|
119 } |
|
120 |
|
121 int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) |
|
122 { |
|
123 int success; |
|
124 |
|
125 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); |
|
126 success = 0; |
|
127 |
|
128 (void) mon_enter(((struct lock *) lock)->lock_monitor); |
|
129 if (waitflag) |
|
130 while (((struct lock *) lock)->lock_locked) |
|
131 cv_wait(((struct lock *) lock)->lock_condvar); |
|
132 if (!((struct lock *) lock)->lock_locked) { |
|
133 success = 1; |
|
134 ((struct lock *) lock)->lock_locked = 1; |
|
135 } |
|
136 cv_broadcast(((struct lock *) lock)->lock_condvar); |
|
137 mon_exit(((struct lock *) lock)->lock_monitor); |
|
138 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); |
|
139 return success; |
|
140 } |
|
141 |
|
142 void PyThread_release_lock(PyThread_type_lock lock) |
|
143 { |
|
144 dprintf(("PyThread_release_lock(%p) called\n", lock)); |
|
145 (void) mon_enter(((struct lock *) lock)->lock_monitor); |
|
146 ((struct lock *) lock)->lock_locked = 0; |
|
147 cv_broadcast(((struct lock *) lock)->lock_condvar); |
|
148 mon_exit(((struct lock *) lock)->lock_monitor); |
|
149 } |