home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / include / md / _solaris.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  17.8 KB  |  628 lines

  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 Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #ifndef nspr_solaris_defs_h___
  20. #define nspr_solaris_defs_h___
  21.  
  22. /*
  23.  * Internal configuration macros
  24.  */
  25.  
  26. #define PR_LINKER_ARCH    "solaris"
  27. #define _PR_SI_SYSNAME    "SOLARIS"
  28. #define _PR_SI_ARCHITECTURE    "sparc"
  29. #define PR_DLL_SUFFIX        ".so"
  30.  
  31. #define _PR_VMBASE        0x30000000
  32. #define _PR_STACK_VMBASE    0x50000000
  33. #define _MD_DEFAULT_STACK_SIZE    (2*65536L)
  34. #define _MD_MMAP_FLAGS          MAP_SHARED
  35.  
  36. #undef  HAVE_STACK_GROWING_UP
  37.  
  38. #ifndef HAVE_WEAK_IO_SYMBOLS
  39. #define    HAVE_WEAK_IO_SYMBOLS
  40. #endif
  41.  
  42. #undef    HAVE_WEAK_MALLOC_SYMBOLS
  43. #define    HAVE_DLL
  44. #define    USE_DLFCN
  45. #define NEED_STRFTIME_LOCK
  46.  
  47. #ifdef _PR_LOCAL_THREADS_ONLY
  48. #undef _PR_HAVE_ATOMIC_OPS
  49. #else
  50. #define _PR_HAVE_ATOMIC_OPS
  51. #endif
  52.  
  53. PR_EXTERN(PRIntervalTime) _MD_Solaris_GetInterval(void);
  54. #define _MD_GET_INTERVAL                  _MD_Solaris_GetInterval
  55. PR_EXTERN(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);
  56. #define _MD_INTERVAL_PER_SEC              _MD_Solaris_TicksPerSecond
  57.  
  58. #if defined(_PR_HAVE_ATOMIC_OPS)
  59. /*
  60. ** Atomic Operations
  61. */
  62. #define _MD_INIT_ATOMIC()
  63.  
  64. PR_EXTERN(PRInt32) _MD_AtomicIncrement(PRInt32 *val);
  65. #define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
  66.  
  67. PR_EXTERN(PRInt32) _MD_AtomicDecrement(PRInt32 *val);
  68. #define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
  69.  
  70. PR_EXTERN(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
  71. #define _MD_ATOMIC_SET _MD_AtomicSet
  72. #endif /* _PR_HAVE_ATOMIC_OPS */
  73.  
  74. #if defined(_PR_PTHREADS)
  75.  
  76. PR_EXTERN(void)        _MD_EarlyInit(void);
  77.  
  78. #define _MD_EARLY_INIT        _MD_EarlyInit
  79. #define _MD_FINAL_INIT        _PR_UnixInit
  80.  
  81. #elif defined(_PR_GLOBAL_THREADS_ONLY)
  82.  
  83. #include "prthread.h"
  84.  
  85. #include <ucontext.h>
  86.  
  87. /*
  88. ** Iinitialization Related definitions
  89. */
  90.  
  91. PR_EXTERN(void)        _MD_EarlyInit(void);
  92.  
  93. #define _MD_EARLY_INIT        _MD_EarlyInit
  94. #define _MD_FINAL_INIT        _PR_UnixInit
  95.  
  96. #define _MD_GET_SP(threadp)    threadp->md.sp
  97.  
  98. /*
  99. ** Clean-up the thread machine dependent data structure
  100. */
  101. #define    _MD_INIT_THREAD                _MD_InitializeThread
  102. #define    _MD_INIT_ATTACHED_THREAD    _MD_InitializeThread
  103.  
  104. PR_EXTERN(PRStatus) _MD_CreateThread(PRThread *thread, 
  105.                     void (*start)(void *), 
  106.                     PRThreadPriority priority,
  107.                     PRThreadScope scope, 
  108.                     PRThreadState state, 
  109.                     PRUint32 stackSize);
  110. #define _MD_CREATE_THREAD _MD_CreateThread
  111.  
  112. #define    _PR_CONTEXT_TYPE    ucontext_t
  113.  
  114. #define CONTEXT(_thread) (&(_thread)->md.context)
  115.  
  116. #include <thread.h>
  117. #include <sys/lwp.h>
  118. #include <synch.h>
  119.  
  120. extern struct PRLock *_pr_schedLock;
  121.  
  122. /*
  123. ** Thread Local Storage 
  124. */
  125.  
  126. #define THREAD_KEY_T thread_key_t
  127.  
  128. extern struct PRThread *_pr_current_thread_tls();
  129. extern struct _PRCPU *_pr_current_cpu_tls();
  130. extern struct PRThread *_pr_last_thread_tls();
  131.  
  132. extern THREAD_KEY_T threadid_key;
  133. extern THREAD_KEY_T cpuid_key;
  134. extern THREAD_KEY_T last_thread_key;
  135.  
  136. #define _MD_CURRENT_THREAD() _pr_current_thread_tls()
  137. #define _MD_CURRENT_CPU() _pr_current_cpu_tls()
  138. #define _MD_LAST_THREAD() _pr_last_thread_tls()
  139.     
  140. #define _MD_SET_CURRENT_THREAD(newval)             \
  141.     PR_BEGIN_MACRO                    \
  142.     thr_setspecific(threadid_key, (void *)newval);    \
  143.     PR_END_MACRO
  144.  
  145. #define _MD_SET_CURRENT_CPU(newval)             \
  146.     PR_BEGIN_MACRO                    \
  147.     thr_setspecific(cpuid_key, (void *)newval);    \
  148.     PR_END_MACRO
  149.  
  150. #define _MD_SET_LAST_THREAD(newval)                 \
  151.     PR_BEGIN_MACRO                        \
  152.     thr_setspecific(last_thread_key, (void *)newval);    \
  153.     PR_END_MACRO
  154.     
  155. #define    _MD_CLEAN_THREAD(_thread)    _MD_cleanup_thread(_thread)
  156. extern void _MD_exit_thread(PRThread *thread);
  157. #define _MD_EXIT_THREAD(thread)        _MD_exit_thread(thread)
  158.  
  159. #define    _MD_SUSPEND_THREAD(thread)    _MD_Suspend(thread)
  160. #define    _MD_RESUME_THREAD(thread)    thr_continue((thread)->md.handle)
  161.  
  162. /* XXXX Needs to be defined - Prashant */
  163. #define _MD_SUSPEND_CPU(cpu)
  164. #define _MD_RESUME_CPU(cpu)
  165.  
  166. extern void _MD_Begin_SuspendAll(void);
  167. extern void _MD_End_SuspendAll(void);
  168. extern void _MD_End_ResumeAll(void);
  169. #define _MD_BEGIN_SUSPEND_ALL()        _MD_Begin_SuspendAll()
  170. #define _MD_BEGIN_RESUME_ALL()        
  171. #define    _MD_END_SUSPEND_ALL()        _MD_End_SuspendAll()
  172. #define    _MD_END_RESUME_ALL()        _MD_End_ResumeAll()
  173.  
  174. #define _MD_INIT_LOCKS()
  175. #define _MD_NEW_LOCK(md_lockp) (mutex_init(&((md_lockp)->lock),USYNC_THREAD,NULL) ? PR_FAILURE : PR_SUCCESS)
  176. #define _MD_FREE_LOCK(md_lockp) mutex_destroy(&((md_lockp)->lock))
  177. #define _MD_UNLOCK(md_lockp) mutex_unlock(&((md_lockp)->lock))
  178. #define _MD_TEST_AND_LOCK(md_lockp) mutex_trylock(&((md_lockp)->lock))
  179. struct _MDLock;
  180. PR_EXTERN(void) _MD_lock(struct _MDLock *md_lock);
  181. #undef PROFILE_LOCKS
  182. #ifndef PROFILE_LOCKS
  183. #define _MD_LOCK(md_lockp) _MD_lock(md_lockp)
  184. #else
  185. #define _MD_LOCK(md_lockp)                 \
  186.     PR_BEGIN_MACRO \
  187.     int rv = _MD_TEST_AND_LOCK(md_lockp); \
  188.     if (rv == 0) { \
  189.         (md_lockp)->hitcount++; \
  190.     } else { \
  191.         (md_lockp)->misscount++; \
  192.         _MD_lock(md_lockp); \
  193.     } \
  194.     PR_END_MACRO
  195. #endif
  196.  
  197. #define _PR_LOCK_HEAP() if (_pr_heapLock) _MD_LOCK(&_pr_heapLock->md)
  198. #define _PR_UNLOCK_HEAP() if (_pr_heapLock) _MD_UNLOCK(&_pr_heapLock->md)
  199.  
  200. #define _MD_ATTACH_THREAD(threadp)
  201.  
  202.  
  203. #define THR_KEYCREATE thr_keycreate
  204. #define THR_SELF thr_self
  205. #define _MD_NEW_CV(condp) cond_init(&((condp)->cv), USYNC_THREAD, 0)
  206. #define COND_WAIT(condp, mutexp) cond_wait(condp, mutexp)
  207. #define COND_TIMEDWAIT(condp, mutexp, tspec) \
  208.                                      cond_timedwait(condp, mutexp, tspec)
  209. #define _MD_NOTIFY_CV(condp, lockp) cond_signal(&((condp)->cv))
  210. #define _MD_NOTIFYALL_CV(condp,unused) cond_broadcast(&((condp)->cv))    
  211. #define _MD_FREE_CV(condp) cond_destroy(&((condp)->cv))
  212. #define _MD_YIELD() thr_yield()
  213. #include <time.h>
  214. /* 
  215.  * Because clock_gettime() on Solaris/x86 2.4 always generates a
  216.  * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
  217.  * which is implemented using gettimeofday().
  218.  */
  219. #if defined(i386) && defined(SOLARIS2_4)
  220. extern int _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp);
  221. #define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
  222. #else
  223. #define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
  224. #endif  /* i386 && SOLARIS2_4 */
  225.  
  226. #define MUTEX_T mutex_t
  227. #define COND_T cond_t
  228.  
  229. #define _MD_NEW_SEM(md_semp,_val)  sema_init(&((md_semp)->sem),_val,USYNC_THREAD,NULL)
  230. #define _MD_DESTROY_SEM(md_semp) sema_destroy(&((md_semp)->sem))
  231. #define _MD_WAIT_SEM(md_semp) sema_wait(&((md_semp)->sem))
  232. #define _MD_POST_SEM(md_semp) sema_post(&((md_semp)->sem))
  233.  
  234. #define _MD_SAVE_ERRNO(_thread)
  235. #define _MD_RESTORE_ERRNO(_thread)
  236. #define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
  237.  
  238. extern struct _MDLock _pr_ioq_lock;
  239. #define _MD_IOQ_LOCK()        _MD_LOCK(&_pr_ioq_lock)
  240. #define _MD_IOQ_UNLOCK()    _MD_UNLOCK(&_pr_ioq_lock)
  241.  
  242. extern PRStatus _MD_wait(struct PRThread *, PRIntervalTime timeout);
  243. #define _MD_WAIT _MD_wait
  244.  
  245. extern PRStatus _MD_WakeupWaiter(struct PRThread *);
  246. #define _MD_WAKEUP_WAITER _MD_WakeupWaiter
  247.  
  248. PR_EXTERN(void) _MD_InitIO(void);
  249. #define _MD_INIT_IO _MD_InitIO
  250.  
  251. #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)
  252. #define _MD_SWITCH_CONTEXT(_thread)
  253. #define _MD_RESTORE_CONTEXT(_newThread)
  254.  
  255. struct _MDLock {
  256.     MUTEX_T lock;
  257. #ifdef PROFILE_LOCKS
  258.     PRInt32 hitcount;
  259.     PRInt32 misscount;
  260. #endif
  261. };
  262.  
  263. struct _MDCVar {
  264.     COND_T cv;
  265. };
  266.  
  267. struct _MDSemaphore {
  268.     sema_t sem;
  269. };
  270.  
  271. struct _MDThread {
  272.     _PR_CONTEXT_TYPE context;
  273.     thread_t handle;
  274.     lwpid_t lwpid;
  275.     uint_t sp;        /* stack pointer */
  276.     uint_t threadID;    /* ptr to solaris-internal thread id structures */
  277.     struct _MDSemaphore waiter_sem;
  278. };
  279.  
  280. struct _MDThreadStack {
  281.     PRInt8 notused;
  282. };
  283.  
  284. struct _MDSegment {
  285.     PRInt8 notused;
  286. };
  287.  
  288. struct _MDCPU {
  289.     struct _MDCPU_Unix md_unix;
  290. };
  291.  
  292. /* The following defines the unwrapped versions of select() and poll(). */
  293. extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
  294.     fd_set *exceptfds, struct timeval *timeout);
  295. #define _MD_SELECT    _select
  296.  
  297. #include <stropts.h>
  298. #include <poll.h>
  299. #define _MD_POLL _poll
  300. extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
  301.  
  302. PR_BEGIN_EXTERN_C
  303.  
  304. /*
  305. ** Missing function prototypes
  306. */
  307. extern int gethostname (char *name, int namelen);
  308.  
  309. PR_END_EXTERN_C
  310.  
  311. #else /* _PR_GLOBAL_THREADS_ONLY */
  312.  
  313. /*
  314.  * LOCAL_THREADS_ONLY implementation on Solaris
  315.  */
  316.  
  317. #include "prthread.h"
  318.  
  319. #include <errno.h>
  320. #include <ucontext.h>
  321. #include <sys/stack.h>
  322. #include <synch.h>
  323.  
  324. /*
  325. ** Iinitialization Related definitions
  326. */
  327.  
  328. PR_EXTERN(void)                _MD_EarlyInit(void);
  329. PR_EXTERN(void)                _MD_SolarisInit();
  330. #define _MD_EARLY_INIT        _MD_EarlyInit
  331. #define _MD_FINAL_INIT        _MD_SolarisInit
  332. #define    _MD_INIT_THREAD        _MD_InitializeThread
  333.  
  334. #ifdef USE_SETJMP
  335.  
  336. #include <setjmp.h>
  337.  
  338. #define _PR_CONTEXT_TYPE    jmp_buf
  339.  
  340. #ifdef sparc
  341. #define _MD_GET_SP(_t)        (_t)->md.context[2]
  342. #else
  343. #define _MD_GET_SP(_t)        (_t)->md.context[4]
  344. #endif
  345.  
  346. #define PR_NUM_GCREGS        _JBLEN
  347. #define CONTEXT(_thread)    (_thread)->md.context
  348.  
  349. #else  /* ! USE_SETJMP */
  350.  
  351. #ifdef sparc
  352. #define    _PR_CONTEXT_TYPE    ucontext_t
  353. #define _MD_GET_SP(_t)        (_t)->md.context.uc_mcontext.gregs[REG_SP]
  354. /*
  355. ** Sparc's use register windows. the _MD_GetRegisters for the sparc's
  356. ** doesn't actually store anything into the argument buffer; instead the
  357. ** register windows are homed to the stack. I assume that the stack
  358. ** always has room for the registers to spill to...
  359. */
  360. #define PR_NUM_GCREGS        0
  361. #else
  362. #define _PR_CONTEXT_TYPE    unsigned int edi; sigset_t oldMask, blockMask; ucontext_t
  363. #define _MD_GET_SP(_t)        (_t)->md.context.uc_mcontext.gregs[USP]
  364. #define PR_NUM_GCREGS        _JBLEN
  365. #endif
  366.  
  367. #define CONTEXT(_thread)    (&(_thread)->md.context)
  368.  
  369. #endif /* ! USE_SETJMP */
  370.  
  371. #include <time.h>
  372. /* 
  373.  * Because clock_gettime() on Solaris/x86 always generates a
  374.  * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
  375.  * which is implemented using gettimeofday().
  376.  */
  377. #ifdef i386
  378. #define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
  379. #else
  380. #define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
  381. #endif  /* i386 */
  382.  
  383. #define _MD_SAVE_ERRNO(_thread)            (_thread)->md.errcode = errno;
  384. #define _MD_RESTORE_ERRNO(_thread)        errno = (_thread)->md.errcode;
  385.  
  386. #ifdef sparc
  387.  
  388. #ifdef USE_SETJMP
  389. #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)          \
  390.     PR_BEGIN_MACRO                      \
  391.     int *context = (_thread)->md.context;          \
  392.     *status = PR_TRUE;              \
  393.     (void) setjmp(context);                  \
  394.     (_thread)->md.context[1] = (int) ((_sp) - 64); \
  395.     (_thread)->md.context[2] = (int) _main;          \
  396.     (_thread)->md.context[3] = (int) _main + 4; \
  397.     _thread->no_sched = 0; \
  398.     PR_END_MACRO
  399.  
  400. #define _MD_SWITCH_CONTEXT(_thread)    \
  401.     if (!setjmp(CONTEXT(_thread))) { \
  402.     _MD_SAVE_ERRNO(_thread)    \
  403.     _MD_SET_LAST_THREAD(_thread);     \
  404.     _MD_SET_CURRENT_THREAD(_thread);     \
  405.     _PR_Schedule();             \
  406.     }
  407.  
  408. #define _MD_RESTORE_CONTEXT(_newThread)        \
  409. {                     \
  410.     _MD_RESTORE_ERRNO(_newThread)        \
  411.     _MD_SET_CURRENT_THREAD(_newThread); \
  412.     longjmp(CONTEXT(_newThread), 1);    \
  413. }
  414.  
  415. #else
  416. /*
  417. ** Initialize the thread context preparing it to execute _main.
  418. */
  419. #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)                    \
  420.     PR_BEGIN_MACRO                                                          \
  421.     ucontext_t *uc = CONTEXT(_thread);                                    \
  422.     *status = PR_TRUE;                                                    \
  423.     getcontext(uc);                                                        \
  424.     uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);    \
  425.     uc->uc_stack.ss_size = _thread->stack->stackSize;                     \
  426.     uc->uc_stack.ss_flags = 0;                 /* ? */                        \
  427.     uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp;    \
  428.     uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main;                \
  429.     uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4;    \
  430.     uc->uc_flags = UC_ALL;                                                \
  431.     _thread->no_sched = 0;                                                \
  432.     PR_END_MACRO
  433.  
  434. /*
  435. ** Switch away from the current thread context by saving its state and
  436. ** calling the thread scheduler. Reload cpu when we come back from the
  437. ** context switch because it might have changed.
  438. */
  439. #define _MD_SWITCH_CONTEXT(_thread)                    \
  440.     PR_BEGIN_MACRO                                     \
  441.         if (!getcontext(CONTEXT(_thread))) {         \
  442.             _MD_SAVE_ERRNO(_thread);                \
  443.             _MD_SET_LAST_THREAD(_thread);             \
  444.             _PR_Schedule();                             \
  445.         }                                             \
  446.     PR_END_MACRO
  447.  
  448. /*
  449. ** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
  450. ** initialized by _MD_INIT_CONTEXT.
  451. */
  452. #define _MD_RESTORE_CONTEXT(_newThread)                        \
  453.     PR_BEGIN_MACRO                                            \
  454.         ucontext_t *uc = CONTEXT(_newThread);                 \
  455.         uc->uc_mcontext.gregs[11] = 1;                         \
  456.         _MD_RESTORE_ERRNO(_newThread);                        \
  457.         _MD_SET_CURRENT_THREAD(_newThread);                 \
  458.         setcontext(uc);                                           \
  459.     PR_END_MACRO
  460. #endif
  461.  
  462. #else  /* x86 solaris */
  463.  
  464. #ifdef USE_SETJMP
  465.  
  466. #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
  467.     PR_BEGIN_MACRO \
  468.     *status = PR_TRUE; \
  469.     if (setjmp(CONTEXT(_thread))) _main(); \
  470.     _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
  471.     PR_END_MACRO
  472.  
  473. #define _MD_SWITCH_CONTEXT(_thread) \
  474.     if (!setjmp(CONTEXT(_thread))) { \
  475.         _MD_SAVE_ERRNO(_thread) \
  476.         _PR_Schedule();    \
  477.     }
  478.  
  479. #define _MD_RESTORE_CONTEXT(_newThread) \
  480. { \
  481.     _MD_RESTORE_ERRNO(_newThread) \
  482.     _MD_SET_CURRENT_THREAD(_newThread); \
  483.     longjmp(CONTEXT(_newThread), 1); \
  484. }
  485.  
  486. #else /* USE_SETJMP */
  487.  
  488. #define WINDOWSIZE        0
  489.  
  490. int getedi(void);
  491. void setedi(int);
  492.  
  493. #define _MD_INIT_CONTEXT(_thread, _sp, _main, status)          \
  494.     PR_BEGIN_MACRO                    \
  495.     ucontext_t *uc = CONTEXT(_thread);        \
  496.         *status = PR_TRUE;              \
  497.     getcontext(uc);                    \
  498.     /* Force sp to be double aligned! */        \
  499.         uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);    \
  500.     uc->uc_mcontext.gregs[PC] = (int) _main;    \
  501.     (_thread)->no_sched = 0; \
  502.     PR_END_MACRO
  503.  
  504. /* getcontext() may return 1, contrary to what the man page says */
  505. #define _MD_SWITCH_CONTEXT(_thread)            \
  506.     PR_BEGIN_MACRO                    \
  507.     ucontext_t *uc = CONTEXT(_thread);        \
  508.     PR_ASSERT(_thread->no_sched);            \
  509.     sigfillset(&((_thread)->md.blockMask));        \
  510.     sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask),    \
  511.         &((_thread)->md.oldMask));        \
  512.     (_thread)->md.edi = getedi();            \
  513.     if (! getcontext(uc)) {                \
  514.         sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
  515.         uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi;    \
  516.         _MD_SAVE_ERRNO(_thread)            \
  517.             _MD_SET_LAST_THREAD(_thread);            \
  518.         _PR_Schedule();                \
  519.     } else {                    \
  520.         sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
  521.         setedi((_thread)->md.edi);        \
  522.         PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
  523.         _MD_LAST_THREAD()->no_sched = 0;    \
  524.     }                        \
  525.     PR_END_MACRO
  526.  
  527. /*
  528. ** Restore a thread context, saved by _PR_SWITCH_CONTEXT
  529. */
  530. #define _MD_RESTORE_CONTEXT(_newthread)            \
  531.     PR_BEGIN_MACRO                    \
  532.     ucontext_t *uc = CONTEXT(_newthread);        \
  533.     uc->uc_mcontext.gregs[EAX] = 1;            \
  534.     _MD_RESTORE_ERRNO(_newthread)              \
  535.     _MD_SET_CURRENT_THREAD(_newthread);        \
  536.     (_newthread)->no_sched = 1;            \
  537.     setcontext(uc);                    \
  538.     PR_END_MACRO
  539. #endif /* USE_SETJMP */
  540.  
  541. #endif /* sparc */
  542.  
  543. struct _MDLock {
  544.     PRInt8 notused;
  545. };
  546.  
  547. struct _MDCVar {
  548.     PRInt8 notused;
  549. };
  550.  
  551. struct _MDSemaphore {
  552.     PRInt8 notused;
  553. };
  554.  
  555. struct _MDThread {
  556.     _PR_CONTEXT_TYPE context;
  557.     int errcode;
  558.     int id;
  559. };
  560.  
  561. struct _MDThreadStack {
  562.     PRInt8 notused;
  563. };
  564.  
  565. struct _MDSegment {
  566.     PRInt8 notused;
  567. };
  568.  
  569. struct _MDCPU {
  570.     struct _MDCPU_Unix md_unix;
  571. };
  572.  
  573. #ifndef _PR_PTHREADS
  574. #define _MD_INIT_LOCKS()
  575. #endif
  576. #define _MD_NEW_LOCK(lock)                PR_SUCCESS
  577. #define _MD_FREE_LOCK(lock)
  578. #define _MD_LOCK(lock)
  579. #define _MD_UNLOCK(lock)
  580. #define _MD_INIT_IO()
  581. #define _MD_IOQ_LOCK()
  582. #define _MD_IOQ_UNLOCK()
  583.  
  584. #define _MD_INIT_RUNNING_CPU(cpu)        _MD_unix_init_running_cpu(cpu)
  585. #define _MD_INIT_THREAD                    _MD_InitializeThread
  586. #define _MD_EXIT_THREAD(thread)
  587. #define _MD_SUSPEND_THREAD(thread)
  588. #define _MD_RESUME_THREAD(thread)
  589. #define _MD_CLEAN_THREAD(_thread)
  590.  
  591. extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout);
  592. extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *);
  593. extern PRStatus _MD_InitializeThread(PRThread *thread);
  594. extern void     _MD_SET_PRIORITY(struct _MDThread *thread,
  595.     PRThreadPriority newPri);
  596. extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *),
  597.     PRThreadPriority priority, PRThreadScope scope, PRThreadState state,
  598.         PRUint32 stackSize);
  599.  
  600. PR_EXTERN(PRIntervalTime)                _MD_Solaris_GetInterval(void);
  601. #define _MD_GET_INTERVAL                _MD_Solaris_GetInterval
  602. PR_EXTERN(PRIntervalTime)                _MD_Solaris_TicksPerSecond(void);
  603. #define _MD_INTERVAL_PER_SEC            _MD_Solaris_TicksPerSecond
  604.  
  605. /* The following defines the unwrapped versions of select() and poll(). */
  606. extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
  607.     fd_set *exceptfds, struct timeval *timeout);
  608. #define _MD_SELECT    _select
  609.  
  610. #include <stropts.h>
  611. #include <poll.h>
  612. #define _MD_POLL _poll
  613. extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
  614.  
  615. PR_BEGIN_EXTERN_C
  616.  
  617. /*
  618. ** Missing function prototypes
  619. */
  620. extern int gethostname (char *name, int namelen);
  621.  
  622. PR_END_EXTERN_C
  623.  
  624. #endif /* _PR_GLOBAL_THREADS_ONLY */
  625.  
  626. #endif /* nspr_solaris_defs_h___ */
  627.  
  628.