1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "primpl.h"
7 
8 
9 extern PRBool suspendAllOn;
10 extern PRThread *suspendAllThread;
11 
12 extern void _MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
13 
_MD_Solaris_TicksPerSecond(void)14 PRIntervalTime _MD_Solaris_TicksPerSecond(void)
15 {
16     /*
17      * Ticks have a 10-microsecond resolution.  So there are
18      * 100000 ticks per second.
19      */
20     return 100000UL;
21 }
22 
23 /* Interval timers, implemented using gethrtime() */
24 
_MD_Solaris_GetInterval(void)25 PRIntervalTime _MD_Solaris_GetInterval(void)
26 {
27     union {
28         hrtime_t hrt;  /* hrtime_t is a 64-bit (long long) integer */
29         PRInt64 pr64;
30     } time;
31     PRInt64 resolution;
32     PRIntervalTime ticks;
33 
34     time.hrt = gethrtime();  /* in nanoseconds */
35     /*
36      * Convert from nanoseconds to ticks.  A tick's resolution is
37      * 10 microseconds, or 10000 nanoseconds.
38      */
39     LL_I2L(resolution, 10000);
40     LL_DIV(time.pr64, time.pr64, resolution);
41     LL_L2UI(ticks, time.pr64);
42     return ticks;
43 }
44 
45 #ifdef _PR_PTHREADS
_MD_EarlyInit(void)46 void _MD_EarlyInit(void)
47 {
48 }
49 
_MD_HomeGCRegisters(PRThread * t,PRIntn isCurrent,PRIntn * np)50 PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
51 {
52     *np = 0;
53     return NULL;
54 }
55 #endif /* _PR_PTHREADS */
56 
57 #if defined(_PR_LOCAL_THREADS_ONLY)
58 
_MD_EarlyInit(void)59 void _MD_EarlyInit(void)
60 {
61 }
62 
_MD_SolarisInit()63 void _MD_SolarisInit()
64 {
65     _PR_UnixInit();
66 }
67 
68 void
_MD_SET_PRIORITY(_MDThread * thread,PRThreadPriority newPri)69 _MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
70 {
71     return;
72 }
73 
74 PRStatus
_MD_InitializeThread(PRThread * thread)75 _MD_InitializeThread(PRThread *thread)
76 {
77     return PR_SUCCESS;
78 }
79 
80 PRStatus
_MD_WAIT(PRThread * thread,PRIntervalTime ticks)81 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
82 {
83     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
84     _PR_MD_SWITCH_CONTEXT(thread);
85     return PR_SUCCESS;
86 }
87 
88 PRStatus
_MD_WAKEUP_WAITER(PRThread * thread)89 _MD_WAKEUP_WAITER(PRThread *thread)
90 {
91     PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE)));
92     return PR_SUCCESS;
93 }
94 
95 /* These functions should not be called for Solaris */
96 void
_MD_YIELD(void)97 _MD_YIELD(void)
98 {
99     PR_NOT_REACHED("_MD_YIELD should not be called for Solaris");
100 }
101 
102 PRStatus
_MD_CREATE_THREAD(PRThread * thread,void (* start)(void *),PRThreadPriority priority,PRThreadScope scope,PRThreadState state,PRUint32 stackSize)103 _MD_CREATE_THREAD(
104     PRThread *thread,
105     void (*start) (void *),
106     PRThreadPriority priority,
107     PRThreadScope scope,
108     PRThreadState state,
109     PRUint32 stackSize)
110 {
111     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris");
112     return(PR_FAILURE);
113 }
114 
115 #ifdef USE_SETJMP
_MD_HomeGCRegisters(PRThread * t,int isCurrent,int * np)116 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
117 {
118     if (isCurrent) {
119         (void) setjmp(CONTEXT(t));
120     }
121     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
122     return (PRWord *) CONTEXT(t);
123 }
124 #else
_MD_HomeGCRegisters(PRThread * t,PRIntn isCurrent,PRIntn * np)125 PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
126 {
127     if (isCurrent) {
128         (void) getcontext(CONTEXT(t));
129     }
130     *np = NGREG;
131     return (PRWord*) &t->md.context.uc_mcontext.gregs[0];
132 }
133 #endif  /* USE_SETJMP */
134 
135 #endif  /* _PR_LOCAL_THREADS_ONLY */
136 
137 #ifndef _PR_PTHREADS
138 #if defined(i386) && defined(SOLARIS2_4)
139 /*
140  * Because clock_gettime() on Solaris/x86 2.4 always generates a
141  * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
142  * which is implemented using gettimeofday().
143  */
144 
145 int
_pr_solx86_clock_gettime(clockid_t clock_id,struct timespec * tp)146 _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp)
147 {
148     struct timeval tv;
149 
150     if (clock_id != CLOCK_REALTIME) {
151         errno = EINVAL;
152         return -1;
153     }
154 
155     gettimeofday(&tv, NULL);
156     tp->tv_sec = tv.tv_sec;
157     tp->tv_nsec = tv.tv_usec * 1000;
158     return 0;
159 }
160 #endif  /* i386 && SOLARIS2_4 */
161 #endif  /* _PR_PTHREADS */
162