Mercurial > cpython-lru_cache-weakref
comparison Python/thread.c @ 1184:cf8ddb29e26e legacy-trunk
Added error checking.
Improved coexistance with dl module.
| author | Sjoerd Mullender <sjoerd@acm.org> |
|---|---|
| date | Wed, 13 Jan 1993 12:08:48 +0000 |
| parents | 9ae65ee09735 |
| children | 947f8a347c4f |
comparison
equal
deleted
inserted
replaced
| 1183:64cc5439e10a | 1184:cf8ddb29e26e |
|---|---|
| 12 #include <stdio.h> | 12 #include <stdio.h> |
| 13 #include <signal.h> | 13 #include <signal.h> |
| 14 #include <sys/types.h> | 14 #include <sys/types.h> |
| 15 #include <sys/prctl.h> | 15 #include <sys/prctl.h> |
| 16 #include <ulocks.h> | 16 #include <ulocks.h> |
| 17 #include <errno.h> | |
| 17 | 18 |
| 18 #define MAXPROC 100 /* max # of threads that can be started */ | 19 #define MAXPROC 100 /* max # of threads that can be started */ |
| 19 | 20 |
| 20 static usptr_t *shared_arena; | 21 static usptr_t *shared_arena; |
| 21 static ulock_t count_lock; /* protection for some variables */ | 22 static ulock_t count_lock; /* protection for some variables */ |
| 99 */ | 100 */ |
| 100 void init_thread _P0() | 101 void init_thread _P0() |
| 101 { | 102 { |
| 102 #ifdef __sgi | 103 #ifdef __sgi |
| 103 struct sigaction s; | 104 struct sigaction s; |
| 105 #ifdef USE_DL | |
| 106 long addr, size; | |
| 107 #endif | |
| 104 #endif | 108 #endif |
| 105 | 109 |
| 106 #ifdef DEBUG | 110 #ifdef DEBUG |
| 107 thread_debug = getenv("THREADDEBUG") != 0; | 111 thread_debug = getenv("THREADDEBUG") != 0; |
| 108 #endif | 112 #endif |
| 110 return; | 114 return; |
| 111 initialized = 1; | 115 initialized = 1; |
| 112 dprintf(("init_thread called\n")); | 116 dprintf(("init_thread called\n")); |
| 113 | 117 |
| 114 #ifdef __sgi | 118 #ifdef __sgi |
| 119 #ifdef USE_DL | |
| 120 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0) | |
| 121 perror("usconfig - CONF_INITSIZE (check)"); | |
| 122 if (usconfig(CONF_INITSIZE, size) < 0) | |
| 123 perror("usconfig - CONF_INITSIZE (reset)"); | |
| 124 addr = (long) dl_getrange(size + sizeof(ushdr_t)); | |
| 125 dprintf(("trying to use addr %lx-%lx for shared arena\n", addr, addr+size)); | |
| 126 errno = 0; | |
| 127 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0) | |
| 128 perror("usconfig - CONF_ATTACHADDR (set)"); | |
| 129 #endif | |
| 115 if (usconfig(CONF_INITUSERS, 16) < 0) | 130 if (usconfig(CONF_INITUSERS, 16) < 0) |
| 116 perror("usconfig - CONF_INITUSERS"); | 131 perror("usconfig - CONF_INITUSERS"); |
| 117 my_pid = getpid(); /* so that we know which is the main thread */ | 132 my_pid = getpid(); /* so that we know which is the main thread */ |
| 118 atexit(maybe_exit); | 133 atexit(maybe_exit); |
| 119 s.sa_handler = exit_sig; | 134 s.sa_handler = exit_sig; |
| 126 if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) | 141 if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) |
| 127 perror("usconfig - CONF_ARENATYPE"); | 142 perror("usconfig - CONF_ARENATYPE"); |
| 128 /*usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);*/ | 143 /*usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);*/ |
| 129 if ((shared_arena = usinit(tmpnam(0))) == 0) | 144 if ((shared_arena = usinit(tmpnam(0))) == 0) |
| 130 perror("usinit"); | 145 perror("usinit"); |
| 131 count_lock = usnewlock(shared_arena); | 146 #ifdef USE_DL |
| 147 if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */ | |
| 148 perror("usconfig - CONF_ATTACHADDR (reset)"); | |
| 149 #endif | |
| 150 if ((count_lock = usnewlock(shared_arena)) == NULL) | |
| 151 perror("usnewlock (count_lock)"); | |
| 132 (void) usinitlock(count_lock); | 152 (void) usinitlock(count_lock); |
| 133 wait_lock = usnewlock(shared_arena); | 153 if ((wait_lock = usnewlock(shared_arena)) == NULL) |
| 154 perror("usnewlock (wait_lock)"); | |
| 134 dprintf(("arena start: %lx, arena size: %ld\n", (long) shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena))); | 155 dprintf(("arena start: %lx, arena size: %ld\n", (long) shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena))); |
| 135 #ifdef USE_DL /* for python */ | |
| 136 dl_setrange((long) shared_arena, (long) shared_arena + 64 * 1024); | |
| 137 #endif | |
| 138 #endif | 156 #endif |
| 139 #ifdef sun | 157 #ifdef sun |
| 140 lwp_setstkcache(STACKSIZE, NSTACKS); | 158 lwp_setstkcache(STACKSIZE, NSTACKS); |
| 141 #endif | 159 #endif |
| 142 #ifdef C_THREADS | 160 #ifdef C_THREADS |
| 149 */ | 167 */ |
| 150 int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) | 168 int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) |
| 151 { | 169 { |
| 152 #ifdef sun | 170 #ifdef sun |
| 153 thread_t tid; | 171 thread_t tid; |
| 172 #endif | |
| 173 #if defined(__sgi) && defined(USE_DL) | |
| 174 long addr, size; | |
| 175 static int local_initialized = 0; | |
| 154 #endif | 176 #endif |
| 155 int success = 0; /* init not needed when SOLARIS and */ | 177 int success = 0; /* init not needed when SOLARIS and */ |
| 156 /* C_THREADS implemented properly */ | 178 /* C_THREADS implemented properly */ |
| 157 | 179 |
| 158 dprintf(("start_new_thread called\n")); | 180 dprintf(("start_new_thread called\n")); |
| 159 if (!initialized) | 181 if (!initialized) |
| 160 init_thread(); | 182 init_thread(); |
| 161 #ifdef __sgi | 183 #ifdef __sgi |
| 162 if (ussetlock(count_lock) == 0) | 184 switch (ussetlock(count_lock)) { |
| 163 return 0; | 185 case 0: return 0; |
| 186 case -1: perror("ussetlock (count_lock)"); | |
| 187 } | |
| 164 if (maxpidindex >= MAXPROC) | 188 if (maxpidindex >= MAXPROC) |
| 165 success = -1; | 189 success = -1; |
| 166 else { | 190 else { |
| 167 success = sproc(func, PR_SALL, arg); | 191 #ifdef USE_DL |
| 192 if (!local_initialized) { | |
| 193 if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0) | |
| 194 perror("usconfig - CONF_INITSIZE (check)"); | |
| 195 if (usconfig(CONF_INITSIZE, size) < 0) | |
| 196 perror("usconfig - CONF_INITSIZE (reset)"); | |
| 197 addr = (long) dl_getrange(size + sizeof(ushdr_t)); | |
| 198 dprintf(("trying to use addr %lx-%lx for sproc\n", addr, addr+size)); | |
| 199 errno = 0; | |
| 200 if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0) | |
| 201 perror("usconfig - CONF_ATTACHADDR (set)"); | |
| 202 } | |
| 203 #endif | |
| 204 if ((success = sproc(func, PR_SALL, arg)) < 0) | |
| 205 perror("sproc"); | |
| 206 #ifdef USE_DL | |
| 207 if (!local_initialized) { | |
| 208 if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */ | |
| 209 perror("usconfig - CONF_ATTACHADDR (reset)"); | |
| 210 local_initialized = 1; | |
| 211 } | |
| 212 #endif | |
| 168 if (success >= 0) { | 213 if (success >= 0) { |
| 169 nthreads++; | 214 nthreads++; |
| 170 pidlist[maxpidindex++] = success; | 215 pidlist[maxpidindex++] = success; |
| 171 } | 216 } |
| 172 } | 217 } |
| 173 (void) usunsetlock(count_lock); | 218 if (usunsetlock(count_lock) < 0) |
| 219 perror("usunsetlock (count_lock)"); | |
| 174 #endif | 220 #endif |
| 175 #ifdef SOLARIS | 221 #ifdef SOLARIS |
| 176 (void) thread_create(0, 0, func, arg, THREAD_NEW_LWP); | 222 (void) thread_create(0, 0, func, arg, THREAD_NEW_LWP); |
| 177 #endif | 223 #endif |
| 178 #ifdef sun | 224 #ifdef sun |
| 191 if (no_cleanup) | 237 if (no_cleanup) |
| 192 _exit(0); | 238 _exit(0); |
| 193 else | 239 else |
| 194 exit(0); | 240 exit(0); |
| 195 #ifdef __sgi | 241 #ifdef __sgi |
| 196 (void) ussetlock(count_lock); | 242 if (ussetlock(count_lock) < 0) |
| 243 perror("ussetlock (count_lock)"); | |
| 197 nthreads--; | 244 nthreads--; |
| 198 if (getpid() == my_pid) { | 245 if (getpid() == my_pid) { |
| 199 /* main thread; wait for other threads to exit */ | 246 /* main thread; wait for other threads to exit */ |
| 200 exiting = 1; | 247 exiting = 1; |
| 201 if (do_exit) { | 248 if (do_exit) { |
| 208 (void) kill(pidlist[i], SIGKILL); | 255 (void) kill(pidlist[i], SIGKILL); |
| 209 _exit(exit_status); | 256 _exit(exit_status); |
| 210 } | 257 } |
| 211 } | 258 } |
| 212 waiting_for_threads = 1; | 259 waiting_for_threads = 1; |
| 213 ussetlock(wait_lock); | 260 if (ussetlock(wait_lock) < 0) |
| 261 perror("ussetlock (wait_lock)"); | |
| 214 for (;;) { | 262 for (;;) { |
| 215 if (nthreads < 0) { | 263 if (nthreads < 0) { |
| 216 dprintf(("really exit (%d)\n", exit_status)); | 264 dprintf(("really exit (%d)\n", exit_status)); |
| 217 if (no_cleanup) | 265 if (no_cleanup) |
| 218 _exit(exit_status); | 266 _exit(exit_status); |
| 219 else | 267 else |
| 220 exit(exit_status); | 268 exit(exit_status); |
| 221 } | 269 } |
| 222 usunsetlock(count_lock); | 270 if (usunsetlock(count_lock) < 0) |
| 271 perror("usunsetlock (count_lock)"); | |
| 223 dprintf(("waiting for other threads (%d)\n", nthreads)); | 272 dprintf(("waiting for other threads (%d)\n", nthreads)); |
| 224 ussetlock(wait_lock); | 273 if (ussetlock(wait_lock) < 0) |
| 225 ussetlock(count_lock); | 274 perror("ussetlock (wait_lock)"); |
| 275 if (ussetlock(count_lock) < 0) | |
| 276 perror("ussetlock (count_lock)"); | |
| 226 } | 277 } |
| 227 } | 278 } |
| 228 /* not the main thread */ | 279 /* not the main thread */ |
| 229 if (waiting_for_threads) { | 280 if (waiting_for_threads) { |
| 230 dprintf(("main thread is waiting\n")); | 281 dprintf(("main thread is waiting\n")); |
| 231 usunsetlock(wait_lock); | 282 if (usunsetlock(wait_lock) < 0) |
| 283 perror("usunsetlock (wait_lock)"); | |
| 232 } else if (do_exit) | 284 } else if (do_exit) |
| 233 (void) kill(my_pid, SIGUSR1); | 285 (void) kill(my_pid, SIGUSR1); |
| 234 (void) usunsetlock(count_lock); | 286 if (usunsetlock(count_lock) < 0) |
| 287 perror("usunsetlock (count_lock)"); | |
| 235 _exit(0); | 288 _exit(0); |
| 236 #endif | 289 #endif |
| 237 #ifdef SOLARIS | 290 #ifdef SOLARIS |
| 238 thread_exit(); | 291 thread_exit(); |
| 239 #endif | 292 #endif |
| 299 dprintf(("allocate_lock called\n")); | 352 dprintf(("allocate_lock called\n")); |
| 300 if (!initialized) | 353 if (!initialized) |
| 301 init_thread(); | 354 init_thread(); |
| 302 | 355 |
| 303 #ifdef __sgi | 356 #ifdef __sgi |
| 304 lock = usnewlock(shared_arena); | 357 if ((lock = usnewlock(shared_arena)) == NULL) |
| 358 perror("usnewlock"); | |
| 305 (void) usinitlock(lock); | 359 (void) usinitlock(lock); |
| 306 #endif | 360 #endif |
| 307 #ifdef sun | 361 #ifdef sun |
| 308 lock = (struct lock *) malloc(sizeof(struct lock)); | 362 lock = (struct lock *) malloc(sizeof(struct lock)); |
| 309 lock->lock_locked = 0; | 363 lock->lock_locked = 0; |
| 330 { | 384 { |
| 331 int success; | 385 int success; |
| 332 | 386 |
| 333 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag)); | 387 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag)); |
| 334 #ifdef __sgi | 388 #ifdef __sgi |
| 389 errno = 0; /* clear it just in case */ | |
| 335 if (waitflag) | 390 if (waitflag) |
| 336 success = ussetlock((ulock_t) lock); | 391 success = ussetlock((ulock_t) lock); |
| 337 else | 392 else |
| 338 success = uscsetlock((ulock_t) lock, 1); /* Try it once */ | 393 success = uscsetlock((ulock_t) lock, 1); /* Try it once */ |
| 394 if (success < 0) | |
| 395 perror(waitflag ? "ussetlock" : "uscsetlock"); | |
| 339 #endif | 396 #endif |
| 340 #ifdef sun | 397 #ifdef sun |
| 341 success = 0; | 398 success = 0; |
| 342 | 399 |
| 343 (void) mon_enter(((struct lock *) lock)->lock_monitor); | 400 (void) mon_enter(((struct lock *) lock)->lock_monitor); |
| 357 | 414 |
| 358 void release_lock _P1(lock, type_lock lock) | 415 void release_lock _P1(lock, type_lock lock) |
| 359 { | 416 { |
| 360 dprintf(("release_lock(%lx) called\n", (long)lock)); | 417 dprintf(("release_lock(%lx) called\n", (long)lock)); |
| 361 #ifdef __sgi | 418 #ifdef __sgi |
| 362 (void) usunsetlock((ulock_t) lock); | 419 if (usunsetlock((ulock_t) lock) < 0) |
| 420 perror("usunsetlock"); | |
| 363 #endif | 421 #endif |
| 364 #ifdef sun | 422 #ifdef sun |
| 365 (void) mon_enter(((struct lock *) lock)->lock_monitor); | 423 (void) mon_enter(((struct lock *) lock)->lock_monitor); |
| 366 ((struct lock *) lock)->lock_locked = 0; | 424 ((struct lock *) lock)->lock_locked = 0; |
| 367 cv_broadcast(((struct lock *) lock)->lock_condvar); | 425 cv_broadcast(((struct lock *) lock)->lock_condvar); |
| 381 dprintf(("allocate_sema called\n")); | 439 dprintf(("allocate_sema called\n")); |
| 382 if (!initialized) | 440 if (!initialized) |
| 383 init_thread(); | 441 init_thread(); |
| 384 | 442 |
| 385 #ifdef __sgi | 443 #ifdef __sgi |
| 386 sema = usnewsema(shared_arena, value); | 444 if ((sema = usnewsema(shared_arena, value)) == NULL) |
| 445 perror("usnewsema"); | |
| 387 dprintf(("allocate_sema() -> %lx\n", (long) sema)); | 446 dprintf(("allocate_sema() -> %lx\n", (long) sema)); |
| 388 return (type_sema) sema; | 447 return (type_sema) sema; |
| 389 #endif | 448 #endif |
| 390 } | 449 } |
| 391 | 450 |
| 399 | 458 |
| 400 void down_sema _P1(sema, type_sema sema) | 459 void down_sema _P1(sema, type_sema sema) |
| 401 { | 460 { |
| 402 dprintf(("down_sema(%lx) called\n", (long) sema)); | 461 dprintf(("down_sema(%lx) called\n", (long) sema)); |
| 403 #ifdef __sgi | 462 #ifdef __sgi |
| 404 (void) uspsema((usema_t *) sema); | 463 if (uspsema((usema_t *) sema) < 0) |
| 464 perror("uspsema"); | |
| 405 #endif | 465 #endif |
| 406 dprintf(("down_sema(%lx) return\n", (long) sema)); | 466 dprintf(("down_sema(%lx) return\n", (long) sema)); |
| 407 } | 467 } |
| 408 | 468 |
| 409 void up_sema _P1(sema, type_sema sema) | 469 void up_sema _P1(sema, type_sema sema) |
| 410 { | 470 { |
| 411 dprintf(("up_sema(%lx)\n", (long) sema)); | 471 dprintf(("up_sema(%lx)\n", (long) sema)); |
| 412 #ifdef __sgi | 472 #ifdef __sgi |
| 413 (void) usvsema((usema_t *) sema); | 473 if (usvsema((usema_t *) sema) < 0) |
| 414 #endif | 474 perror("usvsema"); |
| 415 } | 475 #endif |
| 476 } |
