]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | \r |
2 | /* GNU pth threads interface\r | |
3 | http://www.gnu.org/software/pth\r | |
4 | 2000-05-03 Andy Dustman <andy@dustman.net>\r | |
5 | \r | |
6 | Adapted from Posix threads interface\r | |
7 | 12 May 1997 -- david arnold <davida@pobox.com>\r | |
8 | */\r | |
9 | \r | |
10 | #include <stdlib.h>\r | |
11 | #include <string.h>\r | |
12 | #include <pth.h>\r | |
13 | \r | |
14 | /* A pth mutex isn't sufficient to model the Python lock type\r | |
15 | * because pth mutexes can be acquired multiple times by the\r | |
16 | * same thread.\r | |
17 | *\r | |
18 | * The pth_lock struct implements a Python lock as a "locked?" bit\r | |
19 | * and a <condition, mutex> pair. In general, if the bit can be acquired\r | |
20 | * instantly, it is, else the pair is used to block the thread until the\r | |
21 | * bit is cleared.\r | |
22 | */\r | |
23 | \r | |
24 | typedef struct {\r | |
25 | char locked; /* 0=unlocked, 1=locked */\r | |
26 | /* a <cond, mutex> pair to handle an acquire of a locked lock */\r | |
27 | pth_cond_t lock_released;\r | |
28 | pth_mutex_t mut;\r | |
29 | } pth_lock;\r | |
30 | \r | |
31 | #define CHECK_STATUS(name) if (status == -1) { printf("%d ", status); perror(name); error = 1; }\r | |
32 | \r | |
33 | pth_attr_t PyThread_attr;\r | |
34 | \r | |
35 | /*\r | |
36 | * Initialization.\r | |
37 | */\r | |
38 | \r | |
39 | static void PyThread__init_thread(void)\r | |
40 | {\r | |
41 | pth_init();\r | |
42 | PyThread_attr = pth_attr_new();\r | |
43 | pth_attr_set(PyThread_attr, PTH_ATTR_STACK_SIZE, 1<<18);\r | |
44 | pth_attr_set(PyThread_attr, PTH_ATTR_JOINABLE, FALSE);\r | |
45 | }\r | |
46 | \r | |
47 | /*\r | |
48 | * Thread support.\r | |
49 | */\r | |
50 | \r | |
51 | \r | |
52 | long PyThread_start_new_thread(void (*func)(void *), void *arg)\r | |
53 | {\r | |
54 | pth_t th;\r | |
55 | dprintf(("PyThread_start_new_thread called\n"));\r | |
56 | if (!initialized)\r | |
57 | PyThread_init_thread();\r | |
58 | \r | |
59 | th = pth_spawn(PyThread_attr,\r | |
60 | (void* (*)(void *))func,\r | |
61 | (void *)arg\r | |
62 | );\r | |
63 | \r | |
64 | return th;\r | |
65 | }\r | |
66 | \r | |
67 | long PyThread_get_thread_ident(void)\r | |
68 | {\r | |
69 | volatile pth_t threadid;\r | |
70 | if (!initialized)\r | |
71 | PyThread_init_thread();\r | |
72 | /* Jump through some hoops for Alpha OSF/1 */\r | |
73 | threadid = pth_self();\r | |
74 | return (long) *(long *) &threadid;\r | |
75 | }\r | |
76 | \r | |
77 | void PyThread_exit_thread(void)\r | |
78 | {\r | |
79 | dprintf(("PyThread_exit_thread called\n"));\r | |
80 | if (!initialized) {\r | |
81 | exit(0);\r | |
82 | }\r | |
83 | }\r | |
84 | \r | |
85 | /*\r | |
86 | * Lock support.\r | |
87 | */\r | |
88 | PyThread_type_lock PyThread_allocate_lock(void)\r | |
89 | {\r | |
90 | pth_lock *lock;\r | |
91 | int status, error = 0;\r | |
92 | \r | |
93 | dprintf(("PyThread_allocate_lock called\n"));\r | |
94 | if (!initialized)\r | |
95 | PyThread_init_thread();\r | |
96 | \r | |
97 | lock = (pth_lock *) malloc(sizeof(pth_lock));\r | |
98 | memset((void *)lock, '\0', sizeof(pth_lock));\r | |
99 | if (lock) {\r | |
100 | lock->locked = 0;\r | |
101 | status = pth_mutex_init(&lock->mut);\r | |
102 | CHECK_STATUS("pth_mutex_init");\r | |
103 | status = pth_cond_init(&lock->lock_released);\r | |
104 | CHECK_STATUS("pth_cond_init");\r | |
105 | if (error) {\r | |
106 | free((void *)lock);\r | |
107 | lock = NULL;\r | |
108 | }\r | |
109 | }\r | |
110 | dprintf(("PyThread_allocate_lock() -> %p\n", lock));\r | |
111 | return (PyThread_type_lock) lock;\r | |
112 | }\r | |
113 | \r | |
114 | void PyThread_free_lock(PyThread_type_lock lock)\r | |
115 | {\r | |
116 | pth_lock *thelock = (pth_lock *)lock;\r | |
117 | \r | |
118 | dprintf(("PyThread_free_lock(%p) called\n", lock));\r | |
119 | \r | |
120 | free((void *)thelock);\r | |
121 | }\r | |
122 | \r | |
123 | int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)\r | |
124 | {\r | |
125 | int success;\r | |
126 | pth_lock *thelock = (pth_lock *)lock;\r | |
127 | int status, error = 0;\r | |
128 | \r | |
129 | dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));\r | |
130 | \r | |
131 | status = pth_mutex_acquire(&thelock->mut, !waitflag, NULL);\r | |
132 | CHECK_STATUS("pth_mutex_acquire[1]");\r | |
133 | success = thelock->locked == 0;\r | |
134 | if (success) thelock->locked = 1;\r | |
135 | status = pth_mutex_release( &thelock->mut );\r | |
136 | CHECK_STATUS("pth_mutex_release[1]");\r | |
137 | \r | |
138 | if ( !success && waitflag ) {\r | |
139 | /* continue trying until we get the lock */\r | |
140 | \r | |
141 | /* mut must be locked by me -- part of the condition\r | |
142 | * protocol */\r | |
143 | status = pth_mutex_acquire( &thelock->mut, !waitflag, NULL );\r | |
144 | CHECK_STATUS("pth_mutex_acquire[2]");\r | |
145 | while ( thelock->locked ) {\r | |
146 | status = pth_cond_await(&thelock->lock_released,\r | |
147 | &thelock->mut, NULL);\r | |
148 | CHECK_STATUS("pth_cond_await");\r | |
149 | }\r | |
150 | thelock->locked = 1;\r | |
151 | status = pth_mutex_release( &thelock->mut );\r | |
152 | CHECK_STATUS("pth_mutex_release[2]");\r | |
153 | success = 1;\r | |
154 | }\r | |
155 | if (error) success = 0;\r | |
156 | dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));\r | |
157 | return success;\r | |
158 | }\r | |
159 | \r | |
160 | void PyThread_release_lock(PyThread_type_lock lock)\r | |
161 | {\r | |
162 | pth_lock *thelock = (pth_lock *)lock;\r | |
163 | int status, error = 0;\r | |
164 | \r | |
165 | dprintf(("PyThread_release_lock(%p) called\n", lock));\r | |
166 | \r | |
167 | status = pth_mutex_acquire( &thelock->mut, 0, NULL );\r | |
168 | CHECK_STATUS("pth_mutex_acquire[3]");\r | |
169 | \r | |
170 | thelock->locked = 0;\r | |
171 | \r | |
172 | status = pth_mutex_release( &thelock->mut );\r | |
173 | CHECK_STATUS("pth_mutex_release[3]");\r | |
174 | \r | |
175 | /* wake up someone (anyone, if any) waiting on the lock */\r | |
176 | status = pth_cond_notify( &thelock->lock_released, 0 );\r | |
177 | CHECK_STATUS("pth_cond_notify");\r | |
178 | }\r |