[BACK]Return to solaris_pthreads.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc

Annotation of OpenXM_contrib2/asir2000/gc/solaris_pthreads.c, Revision 1.5

1.1       noro        1: /*
                      2:  * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
                      3:  *
                      4:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      5:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      6:  *
                      7:  * Permission is hereby granted to use or copy this program
                      8:  * for any purpose,  provided the above notices are retained on all copies.
                      9:  * Permission to modify the code and to distribute modified code is granted,
                     10:  * provided the above notices are retained, and a notice that the code was
                     11:  * modified is included with the above copyright notice.
                     12:  */
                     13: /*
                     14:  * Support code for Solaris threads.  Provides functionality we wish Sun
                     15:  * had provided.  Relies on some information we probably shouldn't rely on.
1.5     ! noro       16:  * Modified by Peter C. for Solaris Posix Threads.
1.1       noro       17:  */
                     18:
1.5     ! noro       19: # if defined(GC_SOLARIS_PTHREADS)
1.3       noro       20: # include "private/gc_priv.h"
1.1       noro       21: # include <pthread.h>
                     22: # include <thread.h>
                     23: # include <signal.h>
                     24: # include <fcntl.h>
                     25: # include <sys/types.h>
                     26: # include <sys/mman.h>
                     27: # include <sys/time.h>
                     28: # include <sys/resource.h>
                     29: # include <sys/stat.h>
                     30: # include <sys/syscall.h>
                     31: # include <sys/procfs.h>
                     32: # include <sys/lwp.h>
                     33: # include <sys/reg.h>
                     34: # define _CLASSIC_XOPEN_TYPES
                     35: # include <unistd.h>
                     36: # include <errno.h>
1.3       noro       37: # include "private/solaris_threads.h"
1.1       noro       38: # include <stdio.h>
                     39:
                     40: #undef pthread_join
                     41: #undef pthread_create
                     42:
                     43: pthread_cond_t GC_prom_join_cv;                /* Broadcast when any thread terminates */
                     44: pthread_cond_t GC_create_cv;           /* Signalled when a new undetached      */
                     45:                                /* thread starts.                       */
                     46:
                     47: extern GC_bool GC_multithreaded;
                     48:
                     49: /* We use the allocation lock to protect thread-related data structures. */
                     50:
                     51: /* We stop the world using /proc primitives.  This makes some  */
                     52: /* minimal assumptions about the threads implementation.       */
                     53: /* We don't play by the rules, since the rules make this       */
                     54: /* impossible (as of Solaris 2.3).  Also note that as of       */
                     55: /* Solaris 2.3 the various thread and lwp suspension           */
                     56: /* primitives failed to stop threads by the time the request   */
                     57: /* is completed.                                               */
                     58:
                     59:
                     60:
                     61: int GC_pthread_join(pthread_t wait_for, void **status)
                     62: {
                     63:        return GC_thr_join((thread_t)wait_for, NULL, status);
                     64: }
                     65:
                     66:
                     67: int
                     68: GC_pthread_create(pthread_t *new_thread,
                     69:           const pthread_attr_t *attr_in,
                     70:           void * (*thread_execp)(void *), void *arg)
                     71: {
                     72:     int result;
                     73:     GC_thread t;
                     74:     pthread_t my_new_thread;
                     75:     pthread_attr_t  attr;
                     76:     word my_flags = 0;
                     77:     int  flag;
1.2       noro       78:     void * stack = 0;
                     79:     size_t stack_size = 0;
1.1       noro       80:     int    n;
                     81:     struct sched_param schedparam;
                     82:
                     83:     (void)pthread_attr_init(&attr);
1.2       noro       84:     if (attr_in != 0) {
                     85:        (void)pthread_attr_getstacksize(attr_in, &stack_size);
                     86:        (void)pthread_attr_getstackaddr(attr_in, &stack);
                     87:     }
1.1       noro       88:
                     89:     LOCK();
1.5     ! noro       90:     if (!GC_is_initialized) {
        !            91:            GC_init_inner();
1.1       noro       92:     }
                     93:     GC_multithreaded++;
                     94:
                     95:     if (stack == 0) {
                     96:        if (stack_size == 0)
1.2       noro       97:                stack_size = 1048576;
                     98:                          /* ^-- 1 MB (this was GC_min_stack_sz, but that
                     99:                           * violates the pthread_create documentation which
                    100:                           * says the default value if none is supplied is
                    101:                           * 1MB) */
1.1       noro      102:        else
                    103:                stack_size += thr_min_stack();
                    104:
                    105:        stack = (void *)GC_stack_alloc(&stack_size);
                    106:        if (stack == 0) {
                    107:            GC_multithreaded--;
                    108:            UNLOCK();
                    109:            errno = ENOMEM;
                    110:            return -1;
                    111:        }
                    112:     } else {
                    113:        my_flags |= CLIENT_OWNS_STACK;
                    114:     }
                    115:     (void)pthread_attr_setstacksize(&attr, stack_size);
                    116:     (void)pthread_attr_setstackaddr(&attr, stack);
1.2       noro      117:     if (attr_in != 0) {
                    118:        (void)pthread_attr_getscope(attr_in, &n);
                    119:        (void)pthread_attr_setscope(&attr, n);
                    120:        (void)pthread_attr_getschedparam(attr_in, &schedparam);
                    121:        (void)pthread_attr_setschedparam(&attr, &schedparam);
                    122:        (void)pthread_attr_getschedpolicy(attr_in, &n);
                    123:        (void)pthread_attr_setschedpolicy(&attr, n);
                    124:        (void)pthread_attr_getinheritsched(attr_in, &n);
                    125:        (void)pthread_attr_setinheritsched(&attr, n);
1.1       noro      126:
1.2       noro      127:        (void)pthread_attr_getdetachstate(attr_in, &flag);
                    128:        if (flag == PTHREAD_CREATE_DETACHED) {
                    129:                my_flags |= DETACHED;
                    130:        }
                    131:        (void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1.1       noro      132:     }
                    133:     /*
                    134:      * thr_create can call malloc(), which if redirected will
                    135:      * attempt to acquire the allocation lock.
                    136:      * Unlock here to prevent deadlock.
                    137:      */
                    138:
                    139:
                    140: #if 0
                    141: #ifdef I386
                    142:     UNLOCK();
                    143: #endif
                    144: #endif
                    145:     result =
                    146:            pthread_create(&my_new_thread, &attr, thread_execp, arg);
                    147: #if 0
                    148: #ifdef I386
                    149:     LOCK();
                    150: #endif
                    151: #endif
                    152:     if (result == 0) {
                    153:         t = GC_new_thread(my_new_thread);
                    154:         t -> flags = my_flags;
                    155:         if (!(my_flags & DETACHED)) cond_init(&(t->join_cv), USYNC_THREAD, 0);
                    156:         t -> stack = stack;
                    157:         t -> stack_size = stack_size;
                    158:         if (new_thread != 0) *new_thread = my_new_thread;
                    159:         pthread_cond_signal(&GC_create_cv);
                    160:     } else {
                    161:            if (!(my_flags & CLIENT_OWNS_STACK)) {
                    162:                    GC_stack_free(stack, stack_size);
                    163:            }
                    164:            GC_multithreaded--;
                    165:     }
                    166:     UNLOCK();
                    167:     pthread_attr_destroy(&attr);
                    168:     return(result);
                    169: }
                    170:
                    171: # else
                    172:
                    173: #ifndef LINT
                    174:   int GC_no_sunOS_pthreads;
                    175: #endif
                    176:
1.5     ! noro      177: # endif /* GC_SOLARIS_PTHREADS */
1.1       noro      178:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>