Changeset 391 for python/trunk/Python/thread_sgi.h
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Python/thread_sgi.h
r2 r391 9 9 #include <errno.h> 10 10 11 #define HDR_SIZE 2680/* sizeof(ushdr_t) */12 #define MAXPROC 100/* max # of threads that can be started */11 #define HDR_SIZE 2680 /* sizeof(ushdr_t) */ 12 #define MAXPROC 100 /* max # of threads that can be started */ 13 13 14 14 static usptr_t *shared_arena; 15 static ulock_t count_lock; 16 static ulock_t wait_lock; 17 static int waiting_for_threads; 18 static int nthreads; 15 static ulock_t count_lock; /* protection for some variables */ 16 static ulock_t wait_lock; /* lock used to wait for other threads */ 17 static int waiting_for_threads; /* protected by count_lock */ 18 static int nthreads; /* protected by count_lock */ 19 19 static int exit_status; 20 #ifndef NO_EXIT_PROG 21 static int do_exit; /* indicates that the program is to exit */ 22 #endif 23 static int exiting; /* we're already exiting (for maybe_exit) */ 24 static pid_t my_pid; /* PID of main thread */ 20 static int exiting; /* we're already exiting (for maybe_exit) */ 21 static pid_t my_pid; /* PID of main thread */ 25 22 static struct pidlist { 26 pid_t parent; 27 pid_t child; 28 } pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */ 29 static int maxpidindex; /* # of PIDs in pidlist */ 30 31 #ifndef NO_EXIT_PROG 32 /* 33 * This routine is called as a signal handler when another thread 34 * exits. When that happens, we must see whether we have to exit as 35 * well (because of an PyThread_exit_prog()) or whether we should continue on. 36 */ 37 static void exit_sig(void) 38 { 39 d2printf(("exit_sig called\n")); 40 if (exiting && getpid() == my_pid) { 41 d2printf(("already exiting\n")); 42 return; 43 } 44 if (do_exit) { 45 d2printf(("exiting in exit_sig\n")); 46 #ifdef Py_DEBUG 47 if ((thread_debug & 8) == 0) 48 thread_debug &= ~1; /* don't produce debug messages */ 49 #endif 50 PyThread_exit_thread(); 51 } 52 } 53 54 /* 55 * This routine is called when a process calls exit(). If that wasn't 56 * done from the library, we do as if an PyThread_exit_prog() was intended. 57 */ 58 static void maybe_exit(void) 59 { 60 dprintf(("maybe_exit called\n")); 61 if (exiting) { 62 dprintf(("already exiting\n")); 63 return; 64 } 65 PyThread_exit_prog(0); 66 } 67 #endif /* NO_EXIT_PROG */ 68 23 pid_t parent; 24 pid_t child; 25 } pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */ 26 static int maxpidindex; /* # of PIDs in pidlist */ 69 27 /* 70 28 * Initialization. … … 72 30 static void PyThread__init_thread(void) 73 31 { 74 #ifndef NO_EXIT_PROG 75 struct sigaction s; 76 #endif /* NO_EXIT_PROG */ 77 #ifdef USE_DL 78 long addr, size; 79 #endif /* USE_DL */ 80 81 82 #ifdef USE_DL 83 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0) 84 perror("usconfig - CONF_INITSIZE (check)"); 85 if (usconfig(CONF_INITSIZE, size) < 0) 86 perror("usconfig - CONF_INITSIZE (reset)"); 87 addr = (long) dl_getrange(size + HDR_SIZE); 88 dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size)); 89 errno = 0; 90 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0) 91 perror("usconfig - CONF_ATTACHADDR (set)"); 92 #endif /* USE_DL */ 93 if (usconfig(CONF_INITUSERS, 16) < 0) 94 perror("usconfig - CONF_INITUSERS"); 95 my_pid = getpid(); /* so that we know which is the main thread */ 96 #ifndef NO_EXIT_PROG 97 atexit(maybe_exit); 98 s.sa_handler = exit_sig; 99 sigemptyset(&s.sa_mask); 100 /*sigaddset(&s.sa_mask, SIGUSR1);*/ 101 s.sa_flags = 0; 102 sigaction(SIGUSR1, &s, 0); 103 if (prctl(PR_SETEXITSIG, SIGUSR1) < 0) 104 perror("prctl - PR_SETEXITSIG"); 105 #endif /* NO_EXIT_PROG */ 106 if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) 107 perror("usconfig - CONF_ARENATYPE"); 108 usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */ 32 #ifdef USE_DL 33 long addr, size; 34 #endif /* USE_DL */ 35 36 37 #ifdef USE_DL 38 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0) 39 perror("usconfig - CONF_INITSIZE (check)"); 40 if (usconfig(CONF_INITSIZE, size) < 0) 41 perror("usconfig - CONF_INITSIZE (reset)"); 42 addr = (long) dl_getrange(size + HDR_SIZE); 43 dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size)); 44 errno = 0; 45 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0) 46 perror("usconfig - CONF_ATTACHADDR (set)"); 47 #endif /* USE_DL */ 48 if (usconfig(CONF_INITUSERS, 16) < 0) 49 perror("usconfig - CONF_INITUSERS"); 50 my_pid = getpid(); /* so that we know which is the main thread */ 51 if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) 52 perror("usconfig - CONF_ARENATYPE"); 53 usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */ 109 54 #ifdef Py_DEBUG 110 111 112 113 55 if (thread_debug & 4) 56 usconfig(CONF_LOCKTYPE, US_DEBUGPLUS); 57 else if (thread_debug & 2) 58 usconfig(CONF_LOCKTYPE, US_DEBUG); 114 59 #endif /* Py_DEBUG */ 115 116 117 #ifdef USE_DL 118 119 120 #endif /* USE_DL */ 121 122 123 124 125 126 60 if ((shared_arena = usinit(tmpnam(0))) == 0) 61 perror("usinit"); 62 #ifdef USE_DL 63 if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */ 64 perror("usconfig - CONF_ATTACHADDR (reset)"); 65 #endif /* USE_DL */ 66 if ((count_lock = usnewlock(shared_arena)) == NULL) 67 perror("usnewlock (count_lock)"); 68 (void) usinitlock(count_lock); 69 if ((wait_lock = usnewlock(shared_arena)) == NULL) 70 perror("usnewlock (wait_lock)"); 71 dprintf(("arena start: %p, arena size: %ld\n", shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena))); 127 72 } 128 73 … … 133 78 static void clean_threads(void) 134 79 { 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 80 int i, j; 81 pid_t mypid, pid; 82 83 /* clean up any exited threads */ 84 mypid = getpid(); 85 i = 0; 86 while (i < maxpidindex) { 87 if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) { 88 pid = waitpid(pid, 0, WNOHANG); 89 if (pid > 0) { 90 /* a thread has exited */ 91 pidlist[i] = pidlist[--maxpidindex]; 92 /* remove references to children of dead proc */ 93 for (j = 0; j < maxpidindex; j++) 94 if (pidlist[j].parent == pid) 95 pidlist[j].child = -1; 96 continue; /* don't increment i */ 97 } 98 } 99 i++; 100 } 101 /* clean up the list */ 102 i = 0; 103 while (i < maxpidindex) { 104 if (pidlist[i].child == -1) { 105 pidlist[i] = pidlist[--maxpidindex]; 106 continue; /* don't increment i */ 107 } 108 i++; 109 } 165 110 } 166 111 … … 168 113 { 169 114 #ifdef USE_DL 170 171 172 #endif /* USE_DL */ 173 int success = 0;/* init not needed when SOLARIS_THREADS and */174 175 176 177 178 179 180 181 182 183 184 185 186 #ifdef USE_DL 187 188 189 190 191 192 193 194 195 196 197 198 199 200 #endif /* USE_DL */ 201 202 203 204 #ifdef USE_DL 205 206 207 208 209 210 211 #endif /* USE_DL */ 212 213 214 215 216 217 218 219 220 221 222 115 long addr, size; 116 static int local_initialized = 0; 117 #endif /* USE_DL */ 118 int success = 0; /* init not needed when SOLARIS_THREADS and */ 119 /* C_THREADS implemented properly */ 120 121 dprintf(("PyThread_start_new_thread called\n")); 122 if (!initialized) 123 PyThread_init_thread(); 124 switch (ussetlock(count_lock)) { 125 case 0: return 0; 126 case -1: perror("ussetlock (count_lock)"); 127 } 128 if (maxpidindex >= MAXPROC) 129 success = -1; 130 else { 131 #ifdef USE_DL 132 if (!local_initialized) { 133 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0) 134 perror("usconfig - CONF_INITSIZE (check)"); 135 if (usconfig(CONF_INITSIZE, size) < 0) 136 perror("usconfig - CONF_INITSIZE (reset)"); 137 addr = (long) dl_getrange(size + HDR_SIZE); 138 dprintf(("trying to use addr %p-%p for sproc\n", 139 addr, addr+size)); 140 errno = 0; 141 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && 142 errno != 0) 143 perror("usconfig - CONF_ATTACHADDR (set)"); 144 } 145 #endif /* USE_DL */ 146 clean_threads(); 147 if ((success = sproc(func, PR_SALL, arg)) < 0) 148 perror("sproc"); 149 #ifdef USE_DL 150 if (!local_initialized) { 151 if (usconfig(CONF_ATTACHADDR, addr) < 0) 152 /* reset address */ 153 perror("usconfig - CONF_ATTACHADDR (reset)"); 154 local_initialized = 1; 155 } 156 #endif /* USE_DL */ 157 if (success >= 0) { 158 nthreads++; 159 pidlist[maxpidindex].parent = getpid(); 160 pidlist[maxpidindex++].child = success; 161 dprintf(("pidlist[%d] = %d\n", 162 maxpidindex-1, success)); 163 } 164 } 165 if (usunsetlock(count_lock) < 0) 166 perror("usunsetlock (count_lock)"); 167 return success; 223 168 } 224 169 225 170 long PyThread_get_thread_ident(void) 226 171 { 227 return getpid(); 228 } 229 230 static void do_PyThread_exit_thread(int no_cleanup) 231 { 232 dprintf(("PyThread_exit_thread called\n")); 233 if (!initialized) 234 if (no_cleanup) 235 _exit(0); 236 else 237 exit(0); 238 if (ussetlock(count_lock) < 0) 239 perror("ussetlock (count_lock)"); 240 nthreads--; 241 if (getpid() == my_pid) { 242 /* main thread; wait for other threads to exit */ 243 exiting = 1; 244 #ifndef NO_EXIT_PROG 245 if (do_exit) { 246 int i; 247 248 /* notify other threads */ 249 clean_threads(); 250 if (nthreads >= 0) { 251 dprintf(("kill other threads\n")); 252 for (i = 0; i < maxpidindex; i++) 253 if (pidlist[i].child > 0) 254 (void) kill(pidlist[i].child, 255 SIGKILL); 256 _exit(exit_status); 257 } 258 } 259 #endif /* NO_EXIT_PROG */ 260 waiting_for_threads = 1; 261 if (ussetlock(wait_lock) < 0) 262 perror("ussetlock (wait_lock)"); 263 for (;;) { 264 if (nthreads < 0) { 265 dprintf(("really exit (%d)\n", exit_status)); 266 if (no_cleanup) 267 _exit(exit_status); 268 else 269 exit(exit_status); 270 } 271 if (usunsetlock(count_lock) < 0) 272 perror("usunsetlock (count_lock)"); 273 dprintf(("waiting for other threads (%d)\n", nthreads)); 274 if (ussetlock(wait_lock) < 0) 275 perror("ussetlock (wait_lock)"); 276 if (ussetlock(count_lock) < 0) 277 perror("ussetlock (count_lock)"); 278 } 279 } 280 /* not the main thread */ 281 if (waiting_for_threads) { 282 dprintf(("main thread is waiting\n")); 283 if (usunsetlock(wait_lock) < 0) 284 perror("usunsetlock (wait_lock)"); 285 } 286 #ifndef NO_EXIT_PROG 287 else if (do_exit) 288 (void) kill(my_pid, SIGUSR1); 289 #endif /* NO_EXIT_PROG */ 290 if (usunsetlock(count_lock) < 0) 291 perror("usunsetlock (count_lock)"); 292 _exit(0); 172 return getpid(); 293 173 } 294 174 295 175 void PyThread_exit_thread(void) 296 176 { 297 do_PyThread_exit_thread(0); 298 } 299 300 void PyThread__exit_thread(void) 301 { 302 do_PyThread_exit_thread(1); 303 } 304 305 #ifndef NO_EXIT_PROG 306 static void do_PyThread_exit_prog(int status, int no_cleanup) 307 { 308 dprintf(("PyThread_exit_prog(%d) called\n", status)); 309 if (!initialized) 310 if (no_cleanup) 311 _exit(status); 312 else 313 exit(status); 314 do_exit = 1; 315 exit_status = status; 316 do_PyThread_exit_thread(no_cleanup); 317 } 318 319 void PyThread_exit_prog(int status) 320 { 321 do_PyThread_exit_prog(status, 0); 322 } 323 324 void PyThread__exit_prog(int status) 325 { 326 do_PyThread_exit_prog(status, 1); 327 } 328 #endif /* NO_EXIT_PROG */ 177 dprintf(("PyThread_exit_thread called\n")); 178 if (!initialized) 179 exit(0); 180 if (ussetlock(count_lock) < 0) 181 perror("ussetlock (count_lock)"); 182 nthreads--; 183 if (getpid() == my_pid) { 184 /* main thread; wait for other threads to exit */ 185 exiting = 1; 186 waiting_for_threads = 1; 187 if (ussetlock(wait_lock) < 0) 188 perror("ussetlock (wait_lock)"); 189 for (;;) { 190 if (nthreads < 0) { 191 dprintf(("really exit (%d)\n", exit_status)); 192 exit(exit_status); 193 } 194 if (usunsetlock(count_lock) < 0) 195 perror("usunsetlock (count_lock)"); 196 dprintf(("waiting for other threads (%d)\n", nthreads)); 197 if (ussetlock(wait_lock) < 0) 198 perror("ussetlock (wait_lock)"); 199 if (ussetlock(count_lock) < 0) 200 perror("ussetlock (count_lock)"); 201 } 202 } 203 /* not the main thread */ 204 if (waiting_for_threads) { 205 dprintf(("main thread is waiting\n")); 206 if (usunsetlock(wait_lock) < 0) 207 perror("usunsetlock (wait_lock)"); 208 } 209 if (usunsetlock(count_lock) < 0) 210 perror("usunsetlock (count_lock)"); 211 _exit(0); 212 } 329 213 330 214 /* … … 333 217 PyThread_type_lock PyThread_allocate_lock(void) 334 218 { 335 336 337 338 339 340 341 342 343 344 345 219 ulock_t lock; 220 221 dprintf(("PyThread_allocate_lock called\n")); 222 if (!initialized) 223 PyThread_init_thread(); 224 225 if ((lock = usnewlock(shared_arena)) == NULL) 226 perror("usnewlock"); 227 (void) usinitlock(lock); 228 dprintf(("PyThread_allocate_lock() -> %p\n", lock)); 229 return (PyThread_type_lock) lock; 346 230 } 347 231 348 232 void PyThread_free_lock(PyThread_type_lock lock) 349 233 { 350 351 234 dprintf(("PyThread_free_lock(%p) called\n", lock)); 235 usfreelock((ulock_t) lock, shared_arena); 352 236 } 353 237 354 238 int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) 355 239 { 356 357 358 359 errno = 0;/* clear it just in case */360 361 362 363 364 365 366 367 240 int success; 241 242 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); 243 errno = 0; /* clear it just in case */ 244 if (waitflag) 245 success = ussetlock((ulock_t) lock); 246 else 247 success = uscsetlock((ulock_t) lock, 1); /* Try it once */ 248 if (success < 0) 249 perror(waitflag ? "ussetlock" : "uscsetlock"); 250 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); 251 return success; 368 252 } 369 253 370 254 void PyThread_release_lock(PyThread_type_lock lock) 371 255 { 372 373 374 375 } 256 dprintf(("PyThread_release_lock(%p) called\n", lock)); 257 if (usunsetlock((ulock_t) lock) < 0) 258 perror("usunsetlock"); 259 }
Note:
See TracChangeset
for help on using the changeset viewer.