~ubuntu-branches/ubuntu/quantal/libgc/quantal

« back to all changes in this revision

Viewing changes to solaris_pthreads.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2011-02-19 12:19:56 UTC
  • mfrom: (1.3.2 upstream) (0.1.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20110219121956-67rb69xlt5nud3v2
Tags: 1:7.1-5
Upload to unstable

Show diffs side-by-side

added added

removed removed

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