solaris.c (3441B)
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 extern PRBool suspendAllOn; 9 extern PRThread* suspendAllThread; 10 11 extern void _MD_SET_PRIORITY(_MDThread* md, PRThreadPriority newPri); 12 13 PRIntervalTime _MD_Solaris_TicksPerSecond(void) { 14 /* 15 * Ticks have a 10-microsecond resolution. So there are 16 * 100000 ticks per second. 17 */ 18 return 100000UL; 19 } 20 21 /* Interval timers, implemented using gethrtime() */ 22 23 PRIntervalTime _MD_Solaris_GetInterval(void) { 24 union { 25 hrtime_t hrt; /* hrtime_t is a 64-bit (long long) integer */ 26 PRInt64 pr64; 27 } time; 28 PRInt64 resolution; 29 PRIntervalTime ticks; 30 31 time.hrt = gethrtime(); /* in nanoseconds */ 32 /* 33 * Convert from nanoseconds to ticks. A tick's resolution is 34 * 10 microseconds, or 10000 nanoseconds. 35 */ 36 LL_I2L(resolution, 10000); 37 LL_DIV(time.pr64, time.pr64, resolution); 38 LL_L2UI(ticks, time.pr64); 39 return ticks; 40 } 41 42 #ifdef _PR_PTHREADS 43 void _MD_EarlyInit(void) {} 44 45 PRWord* _MD_HomeGCRegisters(PRThread* t, PRIntn isCurrent, PRIntn* np) { 46 *np = 0; 47 return NULL; 48 } 49 #endif /* _PR_PTHREADS */ 50 51 #if defined(_PR_LOCAL_THREADS_ONLY) 52 53 void _MD_EarlyInit(void) {} 54 55 void _MD_SolarisInit() { _PR_UnixInit(); } 56 57 void _MD_SET_PRIORITY(_MDThread* thread, PRThreadPriority newPri) { return; } 58 59 PRStatus _MD_InitializeThread(PRThread* thread) { return PR_SUCCESS; } 60 61 PRStatus _MD_WAIT(PRThread* thread, PRIntervalTime ticks) { 62 PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); 63 _PR_MD_SWITCH_CONTEXT(thread); 64 return PR_SUCCESS; 65 } 66 67 PRStatus _MD_WAKEUP_WAITER(PRThread* thread) { 68 PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE))); 69 return PR_SUCCESS; 70 } 71 72 /* These functions should not be called for Solaris */ 73 void _MD_YIELD(void) { 74 PR_NOT_REACHED("_MD_YIELD should not be called for Solaris"); 75 } 76 77 PRStatus _MD_CREATE_THREAD(PRThread* thread, void (*start)(void*), 78 PRThreadPriority priority, PRThreadScope scope, 79 PRThreadState state, PRUint32 stackSize) { 80 PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris"); 81 return (PR_FAILURE); 82 } 83 84 # ifdef USE_SETJMP 85 PRWord* _MD_HomeGCRegisters(PRThread* t, int isCurrent, int* np) { 86 if (isCurrent) { 87 (void)setjmp(CONTEXT(t)); 88 } 89 *np = sizeof(CONTEXT(t)) / sizeof(PRWord); 90 return (PRWord*)CONTEXT(t); 91 } 92 # else 93 PRWord* _MD_HomeGCRegisters(PRThread* t, PRIntn isCurrent, PRIntn* np) { 94 if (isCurrent) { 95 (void)getcontext(CONTEXT(t)); 96 } 97 *np = NGREG; 98 return (PRWord*)&t->md.context.uc_mcontext.gregs[0]; 99 } 100 # endif /* USE_SETJMP */ 101 102 #endif /* _PR_LOCAL_THREADS_ONLY */ 103 104 #ifndef _PR_PTHREADS 105 # if defined(i386) && defined(SOLARIS2_4) 106 /* 107 * Because clock_gettime() on Solaris/x86 2.4 always generates a 108 * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(), 109 * which is implemented using gettimeofday(). 110 */ 111 112 int _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec* tp) { 113 struct timeval tv; 114 115 if (clock_id != CLOCK_REALTIME) { 116 errno = EINVAL; 117 return -1; 118 } 119 120 gettimeofday(&tv, NULL); 121 tp->tv_sec = tv.tv_sec; 122 tp->tv_nsec = tv.tv_usec * 1000; 123 return 0; 124 } 125 # endif /* i386 && SOLARIS2_4 */ 126 #endif /* _PR_PTHREADS */