Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Python/thread_sgi.h

    r2 r391  
    99#include <errno.h>
    1010
    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 */
    1313
    1414static usptr_t *shared_arena;
    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 */
     15static ulock_t count_lock;      /* protection for some variables */
     16static ulock_t wait_lock;       /* lock used to wait for other threads */
     17static int waiting_for_threads; /* protected by count_lock */
     18static int nthreads;            /* protected by count_lock */
    1919static 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 */
     20static int exiting;             /* we're already exiting (for maybe_exit) */
     21static pid_t my_pid;            /* PID of main thread */
    2522static 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 */
     26static int maxpidindex;         /* # of PIDs in pidlist */
    6927/*
    7028 * Initialization.
     
    7230static void PyThread__init_thread(void)
    7331{
    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 */
    10954#ifdef Py_DEBUG
    110         if (thread_debug & 4)
    111                 usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
    112         else if (thread_debug & 2)
    113                 usconfig(CONF_LOCKTYPE, US_DEBUG);
     55    if (thread_debug & 4)
     56        usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
     57    else if (thread_debug & 2)
     58        usconfig(CONF_LOCKTYPE, US_DEBUG);
    11459#endif /* Py_DEBUG */
    115         if ((shared_arena = usinit(tmpnam(0))) == 0)
    116                 perror("usinit");
    117 #ifdef USE_DL
    118         if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
    119                 perror("usconfig - CONF_ATTACHADDR (reset)");
    120 #endif /* USE_DL */
    121         if ((count_lock = usnewlock(shared_arena)) == NULL)
    122                 perror("usnewlock (count_lock)");
    123         (void) usinitlock(count_lock);
    124         if ((wait_lock = usnewlock(shared_arena)) == NULL)
    125                 perror("usnewlock (wait_lock)");
    126         dprintf(("arena start: %p, arena size: %ld\n",  shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
     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)));
    12772}
    12873
     
    13378static void clean_threads(void)
    13479{
    135         int i, j;
    136         pid_t mypid, pid;
    137 
    138         /* clean up any exited threads */
    139         mypid = getpid();
    140         i = 0;
    141         while (i < maxpidindex) {
    142                 if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
    143                         pid = waitpid(pid, 0, WNOHANG);
    144                         if (pid > 0) {
    145                                 /* a thread has exited */
    146                                 pidlist[i] = pidlist[--maxpidindex];
    147                                 /* remove references to children of dead proc */
    148                                 for (j = 0; j < maxpidindex; j++)
    149                                         if (pidlist[j].parent == pid)
    150                                                 pidlist[j].child = -1;
    151                                 continue; /* don't increment i */
    152                         }
    153                 }
    154                 i++;
    155         }
    156         /* clean up the list */
    157         i = 0;
    158         while (i < maxpidindex) {
    159                 if (pidlist[i].child == -1) {
    160                         pidlist[i] = pidlist[--maxpidindex];
    161                         continue; /* don't increment i */
    162                 }
    163                 i++;
    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    }
    165110}
    166111
     
    168113{
    169114#ifdef USE_DL
    170         long addr, size;
    171         static int local_initialized = 0;
    172 #endif /* USE_DL */
    173         int success = 0;        /* init not needed when SOLARIS_THREADS and */
    174                                 /* C_THREADS implemented properly */
    175 
    176         dprintf(("PyThread_start_new_thread called\n"));
    177         if (!initialized)
    178                 PyThread_init_thread();
    179         switch (ussetlock(count_lock)) {
    180         case 0: return 0;
    181         case -1: perror("ussetlock (count_lock)");
    182         }
    183         if (maxpidindex >= MAXPROC)
    184                 success = -1;
    185         else {
    186 #ifdef USE_DL
    187                 if (!local_initialized) {
    188                         if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
    189                                 perror("usconfig - CONF_INITSIZE (check)");
    190                         if (usconfig(CONF_INITSIZE, size) < 0)
    191                                 perror("usconfig - CONF_INITSIZE (reset)");
    192                         addr = (long) dl_getrange(size + HDR_SIZE);
    193                         dprintf(("trying to use addr %p-%p for sproc\n",
    194                                 addr, addr+size));
    195                         errno = 0;
    196                         if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
    197                             errno != 0)
    198                                 perror("usconfig - CONF_ATTACHADDR (set)");
    199                 }
    200 #endif /* USE_DL */
    201                 clean_threads();
    202                 if ((success = sproc(func, PR_SALL, arg)) < 0)
    203                         perror("sproc");
    204 #ifdef USE_DL
    205                 if (!local_initialized) {
    206                         if (usconfig(CONF_ATTACHADDR, addr) < 0)
    207                                 /* reset address */
    208                                 perror("usconfig - CONF_ATTACHADDR (reset)");
    209                         local_initialized = 1;
    210                 }
    211 #endif /* USE_DL */
    212                 if (success >= 0) {
    213                         nthreads++;
    214                         pidlist[maxpidindex].parent = getpid();
    215                         pidlist[maxpidindex++].child = success;
    216                         dprintf(("pidlist[%d] = %d\n",
    217                                 maxpidindex-1, success));
    218                 }
    219         }
    220         if (usunsetlock(count_lock) < 0)
    221                 perror("usunsetlock (count_lock)");
    222         return success;
     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;
    223168}
    224169
    225170long PyThread_get_thread_ident(void)
    226171{
    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();
    293173}
    294174
    295175void PyThread_exit_thread(void)
    296176{
    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}
    329213
    330214/*
     
    333217PyThread_type_lock PyThread_allocate_lock(void)
    334218{
    335         ulock_t lock;
    336 
    337         dprintf(("PyThread_allocate_lock called\n"));
    338         if (!initialized)
    339                 PyThread_init_thread();
    340 
    341         if ((lock = usnewlock(shared_arena)) == NULL)
    342                 perror("usnewlock");
    343         (void) usinitlock(lock);
    344         dprintf(("PyThread_allocate_lock() -> %p\n", lock));
    345         return (PyThread_type_lock) lock;
     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;
    346230}
    347231
    348232void PyThread_free_lock(PyThread_type_lock lock)
    349233{
    350         dprintf(("PyThread_free_lock(%p) called\n", lock));
    351         usfreelock((ulock_t) lock, shared_arena);
     234    dprintf(("PyThread_free_lock(%p) called\n", lock));
     235    usfreelock((ulock_t) lock, shared_arena);
    352236}
    353237
    354238int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
    355239{
    356         int success;
    357 
    358         dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
    359         errno = 0;              /* clear it just in case */
    360         if (waitflag)
    361                 success = ussetlock((ulock_t) lock);
    362         else
    363                 success = uscsetlock((ulock_t) lock, 1); /* Try it once */
    364         if (success < 0)
    365                 perror(waitflag ? "ussetlock" : "uscsetlock");
    366         dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
    367         return success;
     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;
    368252}
    369253
    370254void PyThread_release_lock(PyThread_type_lock lock)
    371255{
    372         dprintf(("PyThread_release_lock(%p) called\n", lock));
    373         if (usunsetlock((ulock_t) lock) < 0)
    374                 perror("usunsetlock");
    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.