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  */
PyThread__init_thread(void)19 static void PyThread__init_thread(void)
20 {
21     lwp_setstkcache(STACKSIZE, NSTACKS);
22 }
23 
24 /*
25  * Thread support.
26  */
27 
28 
PyThread_start_new_thread(void (* func)(void *),void * arg)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 
PyThread_get_thread_ident(void)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 
PyThread_exit_thread(void)50 void PyThread_exit_thread(void)
51 {
52     dprintf(("PyThread_exit_thread called\n"));
53     if (!initialized)
54         exit(0);
55     lwp_destroy(SELF);
56 }
57 
58 /*
59  * Lock support.
60  */
PyThread_allocate_lock(void)61 PyThread_type_lock PyThread_allocate_lock(void)
62 {
63     struct lock *lock;
64     extern char *malloc(size_t);
65 
66     dprintf(("PyThread_allocate_lock called\n"));
67     if (!initialized)
68         PyThread_init_thread();
69 
70     lock = (struct lock *) malloc(sizeof(struct lock));
71     lock->lock_locked = 0;
72     (void) mon_create(&lock->lock_monitor);
73     (void) cv_create(&lock->lock_condvar, lock->lock_monitor);
74     dprintf(("PyThread_allocate_lock() -> %p\n", lock));
75     return (PyThread_type_lock) lock;
76 }
77 
PyThread_free_lock(PyThread_type_lock lock)78 void PyThread_free_lock(PyThread_type_lock lock)
79 {
80     dprintf(("PyThread_free_lock(%p) called\n", lock));
81     mon_destroy(((struct lock *) lock)->lock_monitor);
82     free((char *) lock);
83 }
84 
PyThread_acquire_lock(PyThread_type_lock lock,int waitflag)85 int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
86 {
87     int success;
88 
89     dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
90     success = 0;
91 
92     (void) mon_enter(((struct lock *) lock)->lock_monitor);
93     if (waitflag)
94         while (((struct lock *) lock)->lock_locked)
95             cv_wait(((struct lock *) lock)->lock_condvar);
96     if (!((struct lock *) lock)->lock_locked) {
97         success = 1;
98         ((struct lock *) lock)->lock_locked = 1;
99     }
100     cv_broadcast(((struct lock *) lock)->lock_condvar);
101     mon_exit(((struct lock *) lock)->lock_monitor);
102     dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
103     return success;
104 }
105 
PyThread_release_lock(PyThread_type_lock lock)106 void PyThread_release_lock(PyThread_type_lock lock)
107 {
108     dprintf(("PyThread_release_lock(%p) called\n", lock));
109     (void) mon_enter(((struct lock *) lock)->lock_monitor);
110     ((struct lock *) lock)->lock_locked = 0;
111     cv_broadcast(((struct lock *) lock)->lock_condvar);
112     mon_exit(((struct lock *) lock)->lock_monitor);
113 }
114