~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/include/md/_solaris.h

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* 
 
3
 * The contents of this file are subject to the Mozilla Public
 
4
 * License Version 1.1 (the "License"); you may not use this file
 
5
 * except in compliance with the License. You may obtain a copy of
 
6
 * the License at http://www.mozilla.org/MPL/
 
7
 * 
 
8
 * Software distributed under the License is distributed on an "AS
 
9
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
 * implied. See the License for the specific language governing
 
11
 * rights and limitations under the License.
 
12
 * 
 
13
 * The Original Code is the Netscape Portable Runtime (NSPR).
 
14
 * 
 
15
 * The Initial Developer of the Original Code is Netscape
 
16
 * Communications Corporation.  Portions created by Netscape are 
 
17
 * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
 
18
 * Rights Reserved.
 
19
 * 
 
20
 * Contributor(s):
 
21
 * 
 
22
 * Alternatively, the contents of this file may be used under the
 
23
 * terms of the GNU General Public License Version 2 or later (the
 
24
 * "GPL"), in which case the provisions of the GPL are applicable 
 
25
 * instead of those above.  If you wish to allow use of your 
 
26
 * version of this file only under the terms of the GPL and not to
 
27
 * allow others to use your version of this file under the MPL,
 
28
 * indicate your decision by deleting the provisions above and
 
29
 * replace them with the notice and other provisions required by
 
30
 * the GPL.  If you do not delete the provisions above, a recipient
 
31
 * may use your version of this file under either the MPL or the
 
32
 * GPL.
 
33
 */
 
34
 
 
35
#ifndef nspr_solaris_defs_h___
 
36
#define nspr_solaris_defs_h___
 
37
 
 
38
/*
 
39
 * Internal configuration macros
 
40
 */
 
41
 
 
42
#define PR_LINKER_ARCH  "solaris"
 
43
#define _PR_SI_SYSNAME  "SOLARIS"
 
44
#ifdef sparc
 
45
#define _PR_SI_ARCHITECTURE     "sparc"
 
46
#elif defined(i386)
 
47
#define _PR_SI_ARCHITECTURE     "x86"
 
48
#else
 
49
#error unknown processor
 
50
#endif
 
51
#define PR_DLL_SUFFIX           ".so"
 
52
 
 
53
#define _PR_VMBASE              0x30000000
 
54
#define _PR_STACK_VMBASE        0x50000000
 
55
#define _MD_DEFAULT_STACK_SIZE  (2*65536L)
 
56
#define _MD_MMAP_FLAGS          MAP_SHARED
 
57
 
 
58
#undef  HAVE_STACK_GROWING_UP
 
59
 
 
60
#ifndef HAVE_WEAK_IO_SYMBOLS
 
61
#define HAVE_WEAK_IO_SYMBOLS
 
62
#endif
 
63
 
 
64
#undef  HAVE_WEAK_MALLOC_SYMBOLS
 
65
#define HAVE_DLL
 
66
#define USE_DLFCN
 
67
#define NEED_STRFTIME_LOCK
 
68
 
 
69
/*
 
70
 * Intel x86 has atomic instructions.
 
71
 *
 
72
 * Sparc v8 does not have instructions to efficiently implement
 
73
 * atomic increment/decrement operations.  In the local threads
 
74
 * only and pthreads versions, we use the default atomic routine
 
75
 * implementation in pratom.c.  The obsolete global threads only
 
76
 * version uses a global mutex_t to implement the atomic routines
 
77
 * in solaris.c, which is actually equivalent to the default
 
78
 * implementation.
 
79
 *
 
80
 * 64-bit Solaris requires sparc v9, which has atomic instructions.
 
81
 */
 
82
#if defined(i386) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(IS_64)
 
83
#define _PR_HAVE_ATOMIC_OPS
 
84
#endif
 
85
 
 
86
#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)
 
87
/*
 
88
 * We have assembly language implementation of atomic
 
89
 * stacks for the 32-bit sparc and x86 architectures only.
 
90
 *
 
91
 * Note: We ran into thread starvation problem with the
 
92
 * 32-bit sparc assembly language implementation of atomic
 
93
 * stacks, so we do not use it now. (Bugzilla bug 113740)
 
94
 */
 
95
#if !defined(sparc)
 
96
#define _PR_HAVE_ATOMIC_CAS
 
97
#endif
 
98
#endif
 
99
 
 
100
#define _PR_POLL_AVAILABLE
 
101
#define _PR_USE_POLL
 
102
#define _PR_STAT_HAS_ST_ATIM
 
103
#ifdef SOLARIS2_5
 
104
#define _PR_HAVE_SYSV_SEMAPHORES
 
105
#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
 
106
#else
 
107
#define _PR_HAVE_POSIX_SEMAPHORES
 
108
#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
 
109
#endif
 
110
#define _PR_HAVE_GETIPNODEBYNAME
 
111
#define _PR_HAVE_GETIPNODEBYADDR
 
112
#define _PR_HAVE_GETADDRINFO
 
113
#define _PR_INET6_PROBE
 
114
#define _PR_ACCEPT_INHERIT_NONBLOCK
 
115
#ifdef _PR_INET6
 
116
#define _PR_HAVE_INET_NTOP
 
117
#else
 
118
#define AF_INET6 26
 
119
struct addrinfo {
 
120
    int ai_flags;
 
121
    int ai_family;
 
122
    int ai_socktype;
 
123
    int ai_protocol;
 
124
    size_t ai_addrlen;
 
125
    char *ai_canonname;
 
126
    struct sockaddr *ai_addr;
 
127
    struct addrinfo *ai_next;
 
128
};
 
129
#define AI_CANONNAME 0x0010
 
130
#define AI_V4MAPPED 0x0001 
 
131
#define AI_ALL      0x0002
 
132
#define AI_ADDRCONFIG   0x0004
 
133
#define _PR_HAVE_MD_SOCKADDR_IN6
 
134
/* isomorphic to struct in6_addr on Solaris 8 */
 
135
struct _md_in6_addr {
 
136
    union {
 
137
        PRUint8  _S6_u8[16];
 
138
        PRUint32 _S6_u32[4];
 
139
        PRUint32 __S6_align;
 
140
    } _S6_un;
 
141
};
 
142
/* isomorphic to struct sockaddr_in6 on Solaris 8 */
 
143
struct _md_sockaddr_in6 {
 
144
    PRUint16 sin6_family;
 
145
    PRUint16 sin6_port;
 
146
    PRUint32 sin6_flowinfo;
 
147
    struct _md_in6_addr sin6_addr;
 
148
    PRUint32 sin6_scope_id;
 
149
    PRUint32 __sin6_src_id;
 
150
};
 
151
#endif
 
152
#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)
 
153
#define _PR_HAVE_GETHOST_R
 
154
#define _PR_HAVE_GETHOST_R_POINTER
 
155
#endif
 
156
 
 
157
#include "prinrval.h"
 
158
NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
 
159
#define _MD_GET_INTERVAL                  _MD_Solaris_GetInterval
 
160
NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);
 
161
#define _MD_INTERVAL_PER_SEC              _MD_Solaris_TicksPerSecond
 
162
 
 
163
#if defined(_PR_HAVE_ATOMIC_OPS)
 
164
/*
 
165
** Atomic Operations
 
166
*/
 
167
#define _MD_INIT_ATOMIC()
 
168
 
 
169
NSPR_API(PRInt32) _MD_AtomicIncrement(PRInt32 *val);
 
170
#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
 
171
 
 
172
NSPR_API(PRInt32) _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val);
 
173
#define _MD_ATOMIC_ADD _MD_AtomicAdd
 
174
 
 
175
NSPR_API(PRInt32) _MD_AtomicDecrement(PRInt32 *val);
 
176
#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
 
177
 
 
178
NSPR_API(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
 
179
#define _MD_ATOMIC_SET _MD_AtomicSet
 
180
#endif /* _PR_HAVE_ATOMIC_OPS */
 
181
 
 
182
#if defined(_PR_PTHREADS)
 
183
 
 
184
NSPR_API(void)          _MD_EarlyInit(void);
 
185
 
 
186
#define _MD_EARLY_INIT          _MD_EarlyInit
 
187
#define _MD_FINAL_INIT          _PR_UnixInit
 
188
 
 
189
#elif defined(_PR_GLOBAL_THREADS_ONLY)
 
190
 
 
191
#include "prthread.h"
 
192
 
 
193
#include <ucontext.h>
 
194
 
 
195
/*
 
196
** Iinitialization Related definitions
 
197
*/
 
198
 
 
199
NSPR_API(void)          _MD_EarlyInit(void);
 
200
 
 
201
#define _MD_EARLY_INIT          _MD_EarlyInit
 
202
#define _MD_FINAL_INIT          _PR_UnixInit
 
203
 
 
204
#define _MD_GET_SP(threadp)     threadp->md.sp
 
205
 
 
206
/*
 
207
** Clean-up the thread machine dependent data structure
 
208
*/
 
209
#define _MD_INIT_THREAD                         _MD_InitializeThread
 
210
#define _MD_INIT_ATTACHED_THREAD        _MD_InitializeThread
 
211
 
 
212
NSPR_API(PRStatus) _MD_CreateThread(PRThread *thread, 
 
213
                                        void (*start)(void *), 
 
214
                                        PRThreadPriority priority,
 
215
                                        PRThreadScope scope, 
 
216
                                        PRThreadState state, 
 
217
                                        PRUint32 stackSize);
 
218
#define _MD_CREATE_THREAD _MD_CreateThread
 
219
 
 
220
#define _PR_CONTEXT_TYPE        ucontext_t
 
221
 
 
222
#define CONTEXT(_thread) (&(_thread)->md.context)
 
223
 
 
224
#include <thread.h>
 
225
#include <sys/lwp.h>
 
226
#include <synch.h>
 
227
 
 
228
extern struct PRLock *_pr_schedLock;
 
229
 
 
230
/*
 
231
** Thread Local Storage 
 
232
*/
 
233
 
 
234
#define THREAD_KEY_T thread_key_t
 
235
 
 
236
extern struct PRThread *_pr_attached_thread_tls();
 
237
extern struct PRThread *_pr_current_thread_tls();
 
238
extern struct _PRCPU *_pr_current_cpu_tls();
 
239
extern struct PRThread *_pr_last_thread_tls();
 
240
 
 
241
extern THREAD_KEY_T threadid_key;
 
242
extern THREAD_KEY_T cpuid_key;
 
243
extern THREAD_KEY_T last_thread_key;
 
244
 
 
245
#define _MD_GET_ATTACHED_THREAD() _pr_attached_thread_tls()
 
246
#define _MD_CURRENT_THREAD() _pr_current_thread_tls()
 
247
#define _MD_CURRENT_CPU() _pr_current_cpu_tls()
 
248
#define _MD_LAST_THREAD() _pr_last_thread_tls()
 
249
        
 
250
#define _MD_SET_CURRENT_THREAD(newval)                  \
 
251
        PR_BEGIN_MACRO                                  \
 
252
        thr_setspecific(threadid_key, (void *)newval);  \
 
253
        PR_END_MACRO
 
254
 
 
255
#define _MD_SET_CURRENT_CPU(newval)                     \
 
256
        PR_BEGIN_MACRO                                  \
 
257
        thr_setspecific(cpuid_key, (void *)newval);     \
 
258
        PR_END_MACRO
 
259
 
 
260
#define _MD_SET_LAST_THREAD(newval)                             \
 
261
        PR_BEGIN_MACRO                                          \
 
262
        thr_setspecific(last_thread_key, (void *)newval);       \
 
263
        PR_END_MACRO
 
264
        
 
265
#define _MD_CLEAN_THREAD(_thread)       _MD_cleanup_thread(_thread)
 
266
extern void _MD_exit_thread(PRThread *thread);
 
267
#define _MD_EXIT_THREAD(thread)         _MD_exit_thread(thread)
 
268
 
 
269
#define _MD_SUSPEND_THREAD(thread)      _MD_Suspend(thread)
 
270
#define _MD_RESUME_THREAD(thread)       thr_continue((thread)->md.handle)
 
271
 
 
272
/* XXXX Needs to be defined - Prashant */
 
273
#define _MD_SUSPEND_CPU(cpu)
 
274
#define _MD_RESUME_CPU(cpu)
 
275
 
 
276
extern void _MD_Begin_SuspendAll(void);
 
277
extern void _MD_End_SuspendAll(void);
 
278
extern void _MD_End_ResumeAll(void);
 
279
#define _MD_BEGIN_SUSPEND_ALL()         _MD_Begin_SuspendAll()
 
280
#define _MD_BEGIN_RESUME_ALL()          
 
281
#define _MD_END_SUSPEND_ALL()           _MD_End_SuspendAll()
 
282
#define _MD_END_RESUME_ALL()            _MD_End_ResumeAll()
 
283
 
 
284
#define _MD_INIT_LOCKS()
 
285
#define _MD_NEW_LOCK(md_lockp) (mutex_init(&((md_lockp)->lock),USYNC_THREAD,NULL) ? PR_FAILURE : PR_SUCCESS)
 
286
#define _MD_FREE_LOCK(md_lockp) mutex_destroy(&((md_lockp)->lock))
 
287
#define _MD_UNLOCK(md_lockp) mutex_unlock(&((md_lockp)->lock))
 
288
#define _MD_TEST_AND_LOCK(md_lockp) mutex_trylock(&((md_lockp)->lock))
 
289
struct _MDLock;
 
290
NSPR_API(void) _MD_lock(struct _MDLock *md_lock);
 
291
#undef PROFILE_LOCKS
 
292
#ifndef PROFILE_LOCKS
 
293
#define _MD_LOCK(md_lockp) _MD_lock(md_lockp)
 
294
#else
 
295
#define _MD_LOCK(md_lockp)                 \
 
296
    PR_BEGIN_MACRO \
 
297
    int rv = _MD_TEST_AND_LOCK(md_lockp); \
 
298
    if (rv == 0) { \
 
299
        (md_lockp)->hitcount++; \
 
300
    } else { \
 
301
        (md_lockp)->misscount++; \
 
302
        _MD_lock(md_lockp); \
 
303
    } \
 
304
    PR_END_MACRO
 
305
#endif
 
306
 
 
307
#define _PR_LOCK_HEAP() if (_pr_heapLock) _MD_LOCK(&_pr_heapLock->md)
 
308
#define _PR_UNLOCK_HEAP() if (_pr_heapLock) _MD_UNLOCK(&_pr_heapLock->md)
 
309
 
 
310
#define _MD_ATTACH_THREAD(threadp)
 
311
 
 
312
 
 
313
#define THR_KEYCREATE thr_keycreate
 
314
#define THR_SELF thr_self
 
315
#define _MD_NEW_CV(condp) cond_init(&((condp)->cv), USYNC_THREAD, 0)
 
316
#define COND_WAIT(condp, mutexp) cond_wait(condp, mutexp)
 
317
#define COND_TIMEDWAIT(condp, mutexp, tspec) \
 
318
                                     cond_timedwait(condp, mutexp, tspec)
 
319
#define _MD_NOTIFY_CV(condp, lockp) cond_signal(&((condp)->cv))
 
320
#define _MD_NOTIFYALL_CV(condp,unused) cond_broadcast(&((condp)->cv))   
 
321
#define _MD_FREE_CV(condp) cond_destroy(&((condp)->cv))
 
322
#define _MD_YIELD() thr_yield()
 
323
#include <time.h>
 
324
/* 
 
325
 * Because clock_gettime() on Solaris/x86 2.4 always generates a
 
326
 * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
 
327
 * which is implemented using gettimeofday().
 
328
 */
 
329
#if defined(i386) && defined(SOLARIS2_4)
 
330
extern int _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp);
 
331
#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
 
332
#else
 
333
#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
 
334
#endif  /* i386 && SOLARIS2_4 */
 
335
 
 
336
#define MUTEX_T mutex_t
 
337
#define COND_T cond_t
 
338
 
 
339
#define _MD_NEW_SEM(md_semp,_val)  sema_init(&((md_semp)->sem),_val,USYNC_THREAD,NULL)
 
340
#define _MD_DESTROY_SEM(md_semp) sema_destroy(&((md_semp)->sem))
 
341
#define _MD_WAIT_SEM(md_semp) sema_wait(&((md_semp)->sem))
 
342
#define _MD_POST_SEM(md_semp) sema_post(&((md_semp)->sem))
 
343
 
 
344
#define _MD_SAVE_ERRNO(_thread)
 
345
#define _MD_RESTORE_ERRNO(_thread)
 
346
#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
 
347
 
 
348
extern struct _MDLock _pr_ioq_lock;
 
349
#define _MD_IOQ_LOCK()          _MD_LOCK(&_pr_ioq_lock)
 
350
#define _MD_IOQ_UNLOCK()        _MD_UNLOCK(&_pr_ioq_lock)
 
351
 
 
352
extern PRStatus _MD_wait(struct PRThread *, PRIntervalTime timeout);
 
353
#define _MD_WAIT _MD_wait
 
354
 
 
355
extern PRStatus _MD_WakeupWaiter(struct PRThread *);
 
356
#define _MD_WAKEUP_WAITER _MD_WakeupWaiter
 
357
 
 
358
NSPR_API(void) _MD_InitIO(void);
 
359
#define _MD_INIT_IO _MD_InitIO
 
360
 
 
361
#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
 
362
    PR_BEGIN_MACRO \
 
363
    *status = PR_TRUE; \
 
364
    PR_END_MACRO
 
365
#define _MD_SWITCH_CONTEXT(_thread)
 
366
#define _MD_RESTORE_CONTEXT(_newThread)
 
367
 
 
368
struct _MDLock {
 
369
    MUTEX_T lock;
 
370
#ifdef PROFILE_LOCKS
 
371
    PRInt32 hitcount;
 
372
    PRInt32 misscount;
 
373
#endif
 
374
};
 
375
 
 
376
struct _MDCVar {
 
377
    COND_T cv;
 
378
};
 
379
 
 
380
struct _MDSemaphore {
 
381
    sema_t sem;
 
382
};
 
383
 
 
384
struct _MDThread {
 
385
    _PR_CONTEXT_TYPE context;
 
386
    thread_t handle;
 
387
    lwpid_t lwpid;
 
388
    uint_t sp;          /* stack pointer */
 
389
    uint_t threadID;    /* ptr to solaris-internal thread id structures */
 
390
    struct _MDSemaphore waiter_sem;
 
391
};
 
392
 
 
393
struct _MDThreadStack {
 
394
    PRInt8 notused;
 
395
};
 
396
 
 
397
struct _MDSegment {
 
398
    PRInt8 notused;
 
399
};
 
400
 
 
401
/*
 
402
 * md-specific cpu structure field, common to all Unix platforms
 
403
 */
 
404
#define _PR_MD_MAX_OSFD FD_SETSIZE
 
405
 
 
406
struct _MDCPU_Unix {
 
407
    PRCList ioQ;
 
408
    PRUint32 ioq_timeout;
 
409
    PRInt32 ioq_max_osfd;
 
410
    PRInt32 ioq_osfd_cnt;
 
411
#ifndef _PR_USE_POLL
 
412
    fd_set fd_read_set, fd_write_set, fd_exception_set;
 
413
    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
 
414
                                fd_exception_cnt[_PR_MD_MAX_OSFD];
 
415
#else
 
416
        struct pollfd *ioq_pollfds;
 
417
        int ioq_pollfds_size;
 
418
#endif  /* _PR_USE_POLL */
 
419
};
 
420
 
 
421
#define _PR_IOQ(_cpu)                   ((_cpu)->md.md_unix.ioQ)
 
422
#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
 
423
#define _PR_FD_READ_SET(_cpu)           ((_cpu)->md.md_unix.fd_read_set)
 
424
#define _PR_FD_READ_CNT(_cpu)           ((_cpu)->md.md_unix.fd_read_cnt)
 
425
#define _PR_FD_WRITE_SET(_cpu)          ((_cpu)->md.md_unix.fd_write_set)
 
426
#define _PR_FD_WRITE_CNT(_cpu)          ((_cpu)->md.md_unix.fd_write_cnt)
 
427
#define _PR_FD_EXCEPTION_SET(_cpu)      ((_cpu)->md.md_unix.fd_exception_set)
 
428
#define _PR_FD_EXCEPTION_CNT(_cpu)      ((_cpu)->md.md_unix.fd_exception_cnt)
 
429
#define _PR_IOQ_TIMEOUT(_cpu)           ((_cpu)->md.md_unix.ioq_timeout)
 
430
#define _PR_IOQ_MAX_OSFD(_cpu)          ((_cpu)->md.md_unix.ioq_max_osfd)
 
431
#define _PR_IOQ_OSFD_CNT(_cpu)          ((_cpu)->md.md_unix.ioq_osfd_cnt)
 
432
#define _PR_IOQ_POLLFDS(_cpu)           ((_cpu)->md.md_unix.ioq_pollfds)
 
433
#define _PR_IOQ_POLLFDS_SIZE(_cpu)      ((_cpu)->md.md_unix.ioq_pollfds_size)
 
434
 
 
435
#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)  32
 
436
 
 
437
 
 
438
struct _MDCPU {
 
439
        struct _MDCPU_Unix md_unix;
 
440
};
 
441
 
 
442
/* The following defines the unwrapped versions of select() and poll(). */
 
443
extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
 
444
        fd_set *exceptfds, struct timeval *timeout);
 
445
#define _MD_SELECT      _select
 
446
 
 
447
#include <poll.h>
 
448
#define _MD_POLL _poll
 
449
extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
 
450
 
 
451
PR_BEGIN_EXTERN_C
 
452
 
 
453
/*
 
454
** Missing function prototypes
 
455
*/
 
456
extern int gethostname (char *name, int namelen);
 
457
 
 
458
PR_END_EXTERN_C
 
459
 
 
460
#else /* _PR_GLOBAL_THREADS_ONLY */
 
461
 
 
462
/*
 
463
 * LOCAL_THREADS_ONLY implementation on Solaris
 
464
 */
 
465
 
 
466
#include "prthread.h"
 
467
 
 
468
#include <errno.h>
 
469
#include <ucontext.h>
 
470
#include <sys/stack.h>
 
471
#include <synch.h>
 
472
 
 
473
/*
 
474
** Iinitialization Related definitions
 
475
*/
 
476
 
 
477
NSPR_API(void)                          _MD_EarlyInit(void);
 
478
NSPR_API(void)                          _MD_SolarisInit();
 
479
#define _MD_EARLY_INIT          _MD_EarlyInit
 
480
#define _MD_FINAL_INIT          _MD_SolarisInit
 
481
#define _MD_INIT_THREAD         _MD_InitializeThread
 
482
 
 
483
#ifdef USE_SETJMP
 
484
 
 
485
#include <setjmp.h>
 
486
 
 
487
#define _PR_CONTEXT_TYPE        jmp_buf
 
488
 
 
489
#ifdef sparc
 
490
#define _MD_GET_SP(_t)          (_t)->md.context[2]
 
491
#else
 
492
#define _MD_GET_SP(_t)          (_t)->md.context[4]
 
493
#endif
 
494
 
 
495
#define PR_NUM_GCREGS           _JBLEN
 
496
#define CONTEXT(_thread)        (_thread)->md.context
 
497
 
 
498
#else  /* ! USE_SETJMP */
 
499
 
 
500
#ifdef sparc
 
501
#define _PR_CONTEXT_TYPE        ucontext_t
 
502
#define _MD_GET_SP(_t)          (_t)->md.context.uc_mcontext.gregs[REG_SP]
 
503
/*
 
504
** Sparc's use register windows. the _MD_GetRegisters for the sparc's
 
505
** doesn't actually store anything into the argument buffer; instead the
 
506
** register windows are homed to the stack. I assume that the stack
 
507
** always has room for the registers to spill to...
 
508
*/
 
509
#define PR_NUM_GCREGS           0
 
510
#else
 
511
#define _PR_CONTEXT_TYPE        unsigned int edi; sigset_t oldMask, blockMask; ucontext_t
 
512
#define _MD_GET_SP(_t)          (_t)->md.context.uc_mcontext.gregs[USP]
 
513
#define PR_NUM_GCREGS           _JBLEN
 
514
#endif
 
515
 
 
516
#define CONTEXT(_thread)        (&(_thread)->md.context)
 
517
 
 
518
#endif /* ! USE_SETJMP */
 
519
 
 
520
#include <time.h>
 
521
/* 
 
522
 * Because clock_gettime() on Solaris/x86 always generates a
 
523
 * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
 
524
 * which is implemented using gettimeofday().
 
525
 */
 
526
#ifdef i386
 
527
#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
 
528
#else
 
529
#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
 
530
#endif  /* i386 */
 
531
 
 
532
#define _MD_SAVE_ERRNO(_thread)                 (_thread)->md.errcode = errno;
 
533
#define _MD_RESTORE_ERRNO(_thread)              errno = (_thread)->md.errcode;
 
534
 
 
535
#ifdef sparc
 
536
 
 
537
#ifdef USE_SETJMP
 
538
#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)         \
 
539
    PR_BEGIN_MACRO                                    \
 
540
        int *context = (_thread)->md.context;         \
 
541
    *status = PR_TRUE;              \
 
542
        (void) setjmp(context);                       \
 
543
        (_thread)->md.context[1] = (int) ((_sp) - 64); \
 
544
        (_thread)->md.context[2] = (int) _main;       \
 
545
        (_thread)->md.context[3] = (int) _main + 4; \
 
546
    _thread->no_sched = 0; \
 
547
    PR_END_MACRO
 
548
 
 
549
#define _MD_SWITCH_CONTEXT(_thread)    \
 
550
    if (!setjmp(CONTEXT(_thread))) { \
 
551
        _MD_SAVE_ERRNO(_thread)    \
 
552
        _MD_SET_LAST_THREAD(_thread);    \
 
553
    _MD_SET_CURRENT_THREAD(_thread);     \
 
554
        _PR_Schedule();              \
 
555
    }
 
556
 
 
557
#define _MD_RESTORE_CONTEXT(_newThread)     \
 
558
{                                    \
 
559
        _MD_RESTORE_ERRNO(_newThread)       \
 
560
        _MD_SET_CURRENT_THREAD(_newThread); \
 
561
    longjmp(CONTEXT(_newThread), 1);    \
 
562
}
 
563
 
 
564
#else
 
565
/*
 
566
** Initialize the thread context preparing it to execute _main.
 
567
*/
 
568
#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)                                   \
 
569
    PR_BEGIN_MACRO                                                                                                      \
 
570
    ucontext_t *uc = CONTEXT(_thread);                                                                  \
 
571
    *status = PR_TRUE;                                                                                                  \
 
572
    getcontext(uc);                                                                                                             \
 
573
    uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);      \
 
574
    uc->uc_stack.ss_size = _thread->stack->stackSize;                                   \
 
575
    uc->uc_stack.ss_flags = 0;                          /* ? */                                 \
 
576
    uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp;  \
 
577
    uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main;                               \
 
578
    uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4;   \
 
579
    uc->uc_flags = UC_ALL;                                                                                              \
 
580
    _thread->no_sched = 0;                                                                                              \
 
581
    PR_END_MACRO
 
582
 
 
583
/*
 
584
** Switch away from the current thread context by saving its state and
 
585
** calling the thread scheduler. Reload cpu when we come back from the
 
586
** context switch because it might have changed.
 
587
*/
 
588
#define _MD_SWITCH_CONTEXT(_thread)                             \
 
589
    PR_BEGIN_MACRO                                              \
 
590
                if (!getcontext(CONTEXT(_thread))) {            \
 
591
                        _MD_SAVE_ERRNO(_thread);                        \
 
592
                        _MD_SET_LAST_THREAD(_thread);                   \
 
593
                        _PR_Schedule();                                                 \
 
594
                }                                                                                       \
 
595
    PR_END_MACRO
 
596
 
 
597
/*
 
598
** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
 
599
** initialized by _MD_INIT_CONTEXT.
 
600
*/
 
601
#define _MD_RESTORE_CONTEXT(_newThread)                                 \
 
602
    PR_BEGIN_MACRO                                                                              \
 
603
        ucontext_t *uc = CONTEXT(_newThread);                           \
 
604
        uc->uc_mcontext.gregs[11] = 1;                                          \
 
605
                _MD_RESTORE_ERRNO(_newThread);                                  \
 
606
                _MD_SET_CURRENT_THREAD(_newThread);                             \
 
607
        setcontext(uc);                                                                 \
 
608
    PR_END_MACRO
 
609
#endif
 
610
 
 
611
#else  /* x86 solaris */
 
612
 
 
613
#ifdef USE_SETJMP
 
614
 
 
615
#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
 
616
    PR_BEGIN_MACRO \
 
617
    *status = PR_TRUE; \
 
618
    if (setjmp(CONTEXT(_thread))) _main(); \
 
619
    _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
 
620
    PR_END_MACRO
 
621
 
 
622
#define _MD_SWITCH_CONTEXT(_thread) \
 
623
    if (!setjmp(CONTEXT(_thread))) { \
 
624
        _MD_SAVE_ERRNO(_thread) \
 
625
        _PR_Schedule(); \
 
626
    }
 
627
 
 
628
#define _MD_RESTORE_CONTEXT(_newThread) \
 
629
{ \
 
630
    _MD_RESTORE_ERRNO(_newThread) \
 
631
    _MD_SET_CURRENT_THREAD(_newThread); \
 
632
    longjmp(CONTEXT(_newThread), 1); \
 
633
}
 
634
 
 
635
#else /* USE_SETJMP */
 
636
 
 
637
#define WINDOWSIZE              0
 
638
 
 
639
int getedi(void);
 
640
void setedi(int);
 
641
 
 
642
#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)         \
 
643
        PR_BEGIN_MACRO                                  \
 
644
        ucontext_t *uc = CONTEXT(_thread);              \
 
645
        *status = PR_TRUE;              \
 
646
        getcontext(uc);                                 \
 
647
        /* Force sp to be double aligned! */            \
 
648
        uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);     \
 
649
        uc->uc_mcontext.gregs[PC] = (int) _main;        \
 
650
        (_thread)->no_sched = 0; \
 
651
        PR_END_MACRO
 
652
 
 
653
/* getcontext() may return 1, contrary to what the man page says */
 
654
#define _MD_SWITCH_CONTEXT(_thread)                     \
 
655
        PR_BEGIN_MACRO                                  \
 
656
        ucontext_t *uc = CONTEXT(_thread);              \
 
657
        PR_ASSERT(_thread->no_sched);                   \
 
658
        sigfillset(&((_thread)->md.blockMask));         \
 
659
        sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask),      \
 
660
                &((_thread)->md.oldMask));              \
 
661
        (_thread)->md.edi = getedi();                   \
 
662
        if (! getcontext(uc)) {                         \
 
663
                sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
 
664
                uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi; \
 
665
                _MD_SAVE_ERRNO(_thread)                 \
 
666
                _MD_SET_LAST_THREAD(_thread);           \
 
667
                _PR_Schedule();                         \
 
668
        } else {                                        \
 
669
                sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
 
670
                setedi((_thread)->md.edi);              \
 
671
                PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
 
672
                _MD_LAST_THREAD()->no_sched = 0;        \
 
673
        }                                               \
 
674
        PR_END_MACRO
 
675
 
 
676
/*
 
677
** Restore a thread context, saved by _PR_SWITCH_CONTEXT
 
678
*/
 
679
#define _MD_RESTORE_CONTEXT(_newthread)                 \
 
680
        PR_BEGIN_MACRO                                  \
 
681
        ucontext_t *uc = CONTEXT(_newthread);           \
 
682
        uc->uc_mcontext.gregs[EAX] = 1;                 \
 
683
        _MD_RESTORE_ERRNO(_newthread)                   \
 
684
        _MD_SET_CURRENT_THREAD(_newthread);             \
 
685
        (_newthread)->no_sched = 1;                     \
 
686
        setcontext(uc);                                 \
 
687
        PR_END_MACRO
 
688
#endif /* USE_SETJMP */
 
689
 
 
690
#endif /* sparc */
 
691
 
 
692
struct _MDLock {
 
693
        PRInt8 notused;
 
694
};
 
695
 
 
696
struct _MDCVar {
 
697
        PRInt8 notused;
 
698
};
 
699
 
 
700
struct _MDSemaphore {
 
701
        PRInt8 notused;
 
702
};
 
703
 
 
704
struct _MDThread {
 
705
    _PR_CONTEXT_TYPE context;
 
706
    int errcode;
 
707
    int id;
 
708
};
 
709
 
 
710
struct _MDThreadStack {
 
711
    PRInt8 notused;
 
712
};
 
713
 
 
714
struct _MDSegment {
 
715
    PRInt8 notused;
 
716
};
 
717
 
 
718
/*
 
719
 * md-specific cpu structure field
 
720
 */
 
721
#define _PR_MD_MAX_OSFD FD_SETSIZE
 
722
 
 
723
struct _MDCPU_Unix {
 
724
    PRCList ioQ;
 
725
    PRUint32 ioq_timeout;
 
726
    PRInt32 ioq_max_osfd;
 
727
    PRInt32 ioq_osfd_cnt;
 
728
#ifndef _PR_USE_POLL
 
729
    fd_set fd_read_set, fd_write_set, fd_exception_set;
 
730
    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
 
731
                                fd_exception_cnt[_PR_MD_MAX_OSFD];
 
732
#else
 
733
        struct pollfd *ioq_pollfds;
 
734
        int ioq_pollfds_size;
 
735
#endif  /* _PR_USE_POLL */
 
736
};
 
737
 
 
738
#define _PR_IOQ(_cpu)                   ((_cpu)->md.md_unix.ioQ)
 
739
#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
 
740
#define _PR_FD_READ_SET(_cpu)           ((_cpu)->md.md_unix.fd_read_set)
 
741
#define _PR_FD_READ_CNT(_cpu)           ((_cpu)->md.md_unix.fd_read_cnt)
 
742
#define _PR_FD_WRITE_SET(_cpu)          ((_cpu)->md.md_unix.fd_write_set)
 
743
#define _PR_FD_WRITE_CNT(_cpu)          ((_cpu)->md.md_unix.fd_write_cnt)
 
744
#define _PR_FD_EXCEPTION_SET(_cpu)      ((_cpu)->md.md_unix.fd_exception_set)
 
745
#define _PR_FD_EXCEPTION_CNT(_cpu)      ((_cpu)->md.md_unix.fd_exception_cnt)
 
746
#define _PR_IOQ_TIMEOUT(_cpu)           ((_cpu)->md.md_unix.ioq_timeout)
 
747
#define _PR_IOQ_MAX_OSFD(_cpu)          ((_cpu)->md.md_unix.ioq_max_osfd)
 
748
#define _PR_IOQ_OSFD_CNT(_cpu)          ((_cpu)->md.md_unix.ioq_osfd_cnt)
 
749
#define _PR_IOQ_POLLFDS(_cpu)           ((_cpu)->md.md_unix.ioq_pollfds)
 
750
#define _PR_IOQ_POLLFDS_SIZE(_cpu)      ((_cpu)->md.md_unix.ioq_pollfds_size)
 
751
 
 
752
#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)  32
 
753
 
 
754
struct _MDCPU {
 
755
        struct _MDCPU_Unix md_unix;
 
756
};
 
757
 
 
758
#ifndef _PR_PTHREADS
 
759
#define _MD_INIT_LOCKS()
 
760
#endif
 
761
#define _MD_NEW_LOCK(lock)                              PR_SUCCESS
 
762
#define _MD_FREE_LOCK(lock)
 
763
#define _MD_LOCK(lock)
 
764
#define _MD_UNLOCK(lock)
 
765
#define _MD_INIT_IO()
 
766
#define _MD_IOQ_LOCK()
 
767
#define _MD_IOQ_UNLOCK()
 
768
 
 
769
#define _MD_INIT_RUNNING_CPU(cpu)               _MD_unix_init_running_cpu(cpu)
 
770
#define _MD_INIT_THREAD                                 _MD_InitializeThread
 
771
#define _MD_EXIT_THREAD(thread)
 
772
#define _MD_SUSPEND_THREAD(thread)
 
773
#define _MD_RESUME_THREAD(thread)
 
774
#define _MD_CLEAN_THREAD(_thread)
 
775
 
 
776
extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout);
 
777
extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *);
 
778
extern void     _MD_YIELD(void);
 
779
extern PRStatus _MD_InitializeThread(PRThread *thread);
 
780
extern void     _MD_SET_PRIORITY(struct _MDThread *thread,
 
781
        PRThreadPriority newPri);
 
782
extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *),
 
783
        PRThreadPriority priority, PRThreadScope scope, PRThreadState state,
 
784
        PRUint32 stackSize);
 
785
 
 
786
NSPR_API(PRIntervalTime)                                _MD_Solaris_GetInterval(void);
 
787
#define _MD_GET_INTERVAL                                _MD_Solaris_GetInterval
 
788
NSPR_API(PRIntervalTime)                                _MD_Solaris_TicksPerSecond(void);
 
789
#define _MD_INTERVAL_PER_SEC                    _MD_Solaris_TicksPerSecond
 
790
 
 
791
/* The following defines the unwrapped versions of select() and poll(). */
 
792
extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
 
793
        fd_set *exceptfds, struct timeval *timeout);
 
794
#define _MD_SELECT      _select
 
795
 
 
796
#include <stropts.h>
 
797
#include <poll.h>
 
798
#define _MD_POLL _poll
 
799
extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
 
800
 
 
801
PR_BEGIN_EXTERN_C
 
802
 
 
803
/*
 
804
** Missing function prototypes
 
805
*/
 
806
extern int gethostname (char *name, int namelen);
 
807
 
 
808
PR_END_EXTERN_C
 
809
 
 
810
#endif /* _PR_GLOBAL_THREADS_ONLY */
 
811
 
 
812
extern void _MD_solaris_map_sendfile_error(int err);
 
813
 
 
814
#endif /* nspr_solaris_defs_h___ */
 
815