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