1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/include/md/_irix.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,438 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nspr_irix_defs_h___ 1.10 +#define nspr_irix_defs_h___ 1.11 + 1.12 +#define _PR_HAVE_ATOMIC_CAS 1.13 + 1.14 +/* 1.15 + * MipsPro assembler defines _LANGUAGE_ASSEMBLY 1.16 + */ 1.17 +#ifndef _LANGUAGE_ASSEMBLY 1.18 + 1.19 +#include "prclist.h" 1.20 +#include "prthread.h" 1.21 +#include <sys/ucontext.h> 1.22 + 1.23 +/* 1.24 + * Internal configuration macros 1.25 + */ 1.26 + 1.27 +#define PR_LINKER_ARCH "irix" 1.28 +#define _PR_SI_SYSNAME "IRIX" 1.29 +#define _PR_SI_ARCHITECTURE "mips" 1.30 +#define PR_DLL_SUFFIX ".so" 1.31 + 1.32 +#define _PR_VMBASE 0x30000000 1.33 +#define _PR_STACK_VMBASE 0x50000000 1.34 +#define _PR_NUM_GCREGS 9 1.35 +#define _MD_MMAP_FLAGS MAP_PRIVATE 1.36 + 1.37 +#define _MD_DEFAULT_STACK_SIZE 65536L 1.38 +#define _MD_MIN_STACK_SIZE 16384L 1.39 + 1.40 +#undef HAVE_STACK_GROWING_UP 1.41 +#define HAVE_WEAK_IO_SYMBOLS 1.42 +#define HAVE_WEAK_MALLOC_SYMBOLS 1.43 +#define HAVE_DLL 1.44 +#define USE_DLFCN 1.45 +#define _PR_HAVE_ATOMIC_OPS 1.46 +#define _PR_POLL_AVAILABLE 1.47 +#define _PR_USE_POLL 1.48 +#define _PR_STAT_HAS_ST_ATIM 1.49 +#define _PR_HAVE_OFF64_T 1.50 +#define HAVE_POINTER_LOCALTIME_R 1.51 +#define _PR_HAVE_POSIX_SEMAPHORES 1.52 +#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY 1.53 +#define _PR_ACCEPT_INHERIT_NONBLOCK 1.54 + 1.55 +#ifdef _PR_INET6 1.56 +#define _PR_HAVE_INET_NTOP 1.57 +#define _PR_HAVE_GETIPNODEBYNAME 1.58 +#define _PR_HAVE_GETIPNODEBYADDR 1.59 +#define _PR_HAVE_GETADDRINFO 1.60 +#endif 1.61 + 1.62 +/* Initialization entry points */ 1.63 +NSPR_API(void) _MD_EarlyInit(void); 1.64 +#define _MD_EARLY_INIT _MD_EarlyInit 1.65 + 1.66 +NSPR_API(void) _MD_IrixInit(void); 1.67 +#define _MD_FINAL_INIT _MD_IrixInit 1.68 + 1.69 +#define _MD_INIT_IO() 1.70 + 1.71 +/* Timer operations */ 1.72 +NSPR_API(PRIntervalTime) _MD_IrixGetInterval(void); 1.73 +#define _MD_GET_INTERVAL _MD_IrixGetInterval 1.74 + 1.75 +NSPR_API(PRIntervalTime) _MD_IrixIntervalPerSec(void); 1.76 +#define _MD_INTERVAL_PER_SEC _MD_IrixIntervalPerSec 1.77 + 1.78 +/* GC operations */ 1.79 +NSPR_API(void *) _MD_GetSP(PRThread *thread); 1.80 +#define _MD_GET_SP _MD_GetSP 1.81 + 1.82 +/* The atomic operations */ 1.83 +#include <mutex.h> 1.84 +#define _MD_INIT_ATOMIC() 1.85 +#define _MD_ATOMIC_INCREMENT(val) add_then_test((unsigned long*)val, 1) 1.86 +#define _MD_ATOMIC_ADD(ptr, val) add_then_test((unsigned long*)ptr, (unsigned long)val) 1.87 +#define _MD_ATOMIC_DECREMENT(val) add_then_test((unsigned long*)val, 0xffffffff) 1.88 +#define _MD_ATOMIC_SET(val, newval) test_and_set((unsigned long*)val, newval) 1.89 + 1.90 +#if defined(_PR_PTHREADS) 1.91 +#else /* defined(_PR_PTHREADS) */ 1.92 + 1.93 +/************************************************************************/ 1.94 + 1.95 +#include <setjmp.h> 1.96 +#include <errno.h> 1.97 +#include <unistd.h> 1.98 +#include <bstring.h> 1.99 +#include <sys/time.h> 1.100 +#include <ulocks.h> 1.101 +#include <sys/prctl.h> 1.102 + 1.103 + 1.104 +/* 1.105 + * Data region private to each sproc. This region is setup by calling 1.106 + * mmap(...,MAP_LOCAL,...). The private data is mapped at the same 1.107 + * address in every sproc, but every sproc gets a private mapping. 1.108 + * 1.109 + * Just make sure that this structure fits in a page, as only one page 1.110 + * is allocated for the private region. 1.111 + */ 1.112 +struct sproc_private_data { 1.113 + struct PRThread *me; 1.114 + struct _PRCPU *cpu; 1.115 + struct PRThread *last; 1.116 + PRUintn intsOff; 1.117 + int sproc_pid; 1.118 +}; 1.119 + 1.120 +extern char *_nspr_sproc_private; 1.121 + 1.122 +#define _PR_PRDA() ((struct sproc_private_data *) _nspr_sproc_private) 1.123 +#define _MD_SET_CURRENT_THREAD(_thread) _PR_PRDA()->me = (_thread) 1.124 +#define _MD_THIS_THREAD() (_PR_PRDA()->me) 1.125 +#define _MD_LAST_THREAD() (_PR_PRDA()->last) 1.126 +#define _MD_SET_LAST_THREAD(_thread) _PR_PRDA()->last = (_thread) 1.127 +#define _MD_CURRENT_CPU() (_PR_PRDA()->cpu) 1.128 +#define _MD_SET_CURRENT_CPU(_cpu) _PR_PRDA()->cpu = (_cpu) 1.129 +#define _MD_SET_INTSOFF(_val) (_PR_PRDA()->intsOff = _val) 1.130 +#define _MD_GET_INTSOFF() (_PR_PRDA()->intsOff) 1.131 + 1.132 +#define _MD_SET_SPROC_PID(_val) (_PR_PRDA()->sproc_pid = _val) 1.133 +#define _MD_GET_SPROC_PID() (_PR_PRDA()->sproc_pid) 1.134 + 1.135 +NSPR_API(struct PRThread*) _MD_get_attached_thread(void); 1.136 +NSPR_API(struct PRThread*) _MD_get_current_thread(void); 1.137 +#define _MD_GET_ATTACHED_THREAD() _MD_get_attached_thread() 1.138 +#define _MD_CURRENT_THREAD() _MD_get_current_thread() 1.139 + 1.140 +#define _MD_CHECK_FOR_EXIT() { \ 1.141 + if (_pr_irix_exit_now) { \ 1.142 + _PR_POST_SEM(_pr_irix_exit_sem); \ 1.143 + _MD_Wakeup_CPUs(); \ 1.144 + _exit(0); \ 1.145 + } \ 1.146 + } 1.147 + 1.148 +#define _MD_ATTACH_THREAD(threadp) 1.149 + 1.150 +#define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno; 1.151 +#define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode; 1.152 + 1.153 +extern struct _PRCPU *_pr_primordialCPU; 1.154 +extern usema_t *_pr_irix_exit_sem; 1.155 +extern PRInt32 _pr_irix_exit_now; 1.156 +extern int _pr_irix_primoridal_cpu_fd[]; 1.157 +extern PRInt32 _pr_irix_process_exit; 1.158 +extern PRInt32 _pr_irix_process_exit_code; 1.159 + 1.160 +/* Thread operations */ 1.161 +#define _PR_LOCK_HEAP() { \ 1.162 + PRIntn _is; \ 1.163 + if (_pr_primordialCPU) { \ 1.164 + if (_MD_GET_ATTACHED_THREAD() && \ 1.165 + !_PR_IS_NATIVE_THREAD( \ 1.166 + _MD_GET_ATTACHED_THREAD())) \ 1.167 + _PR_INTSOFF(_is); \ 1.168 + _PR_LOCK(_pr_heapLock); \ 1.169 + } 1.170 + 1.171 +#define _PR_UNLOCK_HEAP() if (_pr_primordialCPU) { \ 1.172 + _PR_UNLOCK(_pr_heapLock); \ 1.173 + if (_MD_GET_ATTACHED_THREAD() && \ 1.174 + !_PR_IS_NATIVE_THREAD( \ 1.175 + _MD_GET_ATTACHED_THREAD())) \ 1.176 + _PR_INTSON(_is); \ 1.177 + } \ 1.178 + } 1.179 + 1.180 +#define _PR_OPEN_POLL_SEM(_sem) usopenpollsema(_sem, 0666) 1.181 +#define _PR_WAIT_SEM(_sem) uspsema(_sem) 1.182 +#define _PR_POST_SEM(_sem) usvsema(_sem) 1.183 + 1.184 +#define _MD_CVAR_POST_SEM(threadp) usvsema((threadp)->md.cvar_pollsem) 1.185 + 1.186 +#define _MD_IOQ_LOCK() 1.187 +#define _MD_IOQ_UNLOCK() 1.188 + 1.189 +struct _MDLock { 1.190 + ulock_t lock; 1.191 + usptr_t *arena; 1.192 +}; 1.193 + 1.194 +/* 1.195 + * disable pre-emption for the LOCAL threads when calling the arena lock 1.196 + * routines 1.197 + */ 1.198 + 1.199 +#define _PR_LOCK(lock) { \ 1.200 + PRIntn _is; \ 1.201 + PRThread *me = _MD_GET_ATTACHED_THREAD(); \ 1.202 + if (me && !_PR_IS_NATIVE_THREAD(me)) \ 1.203 + _PR_INTSOFF(_is); \ 1.204 + ussetlock(lock); \ 1.205 + if (me && !_PR_IS_NATIVE_THREAD(me)) \ 1.206 + _PR_FAST_INTSON(_is); \ 1.207 + } 1.208 + 1.209 +#define _PR_UNLOCK(lock) { \ 1.210 + PRIntn _is; \ 1.211 + PRThread *me = _MD_GET_ATTACHED_THREAD(); \ 1.212 + if (me && !_PR_IS_NATIVE_THREAD(me)) \ 1.213 + _PR_INTSOFF(_is); \ 1.214 + usunsetlock(lock); \ 1.215 + if (me && !_PR_IS_NATIVE_THREAD(me)) \ 1.216 + _PR_FAST_INTSON(_is); \ 1.217 + } 1.218 + 1.219 +NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md); 1.220 +NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp); 1.221 + 1.222 +#define _MD_LOCK(_lockp) _PR_LOCK((_lockp)->lock) 1.223 +#define _MD_UNLOCK(_lockp) _PR_UNLOCK((_lockp)->lock) 1.224 +#define _MD_TEST_AND_LOCK(_lockp) (uscsetlock((_lockp)->lock, 1) == 0) 1.225 + 1.226 +extern ulock_t _pr_heapLock; 1.227 + 1.228 +struct _MDThread { 1.229 + jmp_buf jb; 1.230 + usptr_t *pollsem_arena; 1.231 + usema_t *cvar_pollsem; 1.232 + PRInt32 cvar_pollsemfd; 1.233 + PRInt32 cvar_pollsem_select; /* acquire sem by calling select */ 1.234 + PRInt32 cvar_wait; /* if 1, thread is waiting on cvar Q */ 1.235 + PRInt32 id; 1.236 + PRInt32 suspending_id; 1.237 + int errcode; 1.238 +}; 1.239 + 1.240 +struct _MDThreadStack { 1.241 + PRInt8 notused; 1.242 +}; 1.243 + 1.244 +struct _MDSemaphore { 1.245 + usema_t *sem; 1.246 +}; 1.247 + 1.248 +struct _MDCVar { 1.249 + ulock_t mdcvar_lock; 1.250 +}; 1.251 + 1.252 +struct _MDSegment { 1.253 + PRInt8 notused; 1.254 +}; 1.255 + 1.256 +/* 1.257 + * md-specific cpu structure field 1.258 + */ 1.259 +#define _PR_MD_MAX_OSFD FD_SETSIZE 1.260 + 1.261 +struct _MDCPU_Unix { 1.262 + PRCList ioQ; 1.263 + PRUint32 ioq_timeout; 1.264 + PRInt32 ioq_max_osfd; 1.265 + PRInt32 ioq_osfd_cnt; 1.266 +#ifndef _PR_USE_POLL 1.267 + fd_set fd_read_set, fd_write_set, fd_exception_set; 1.268 + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], 1.269 + fd_exception_cnt[_PR_MD_MAX_OSFD]; 1.270 +#else 1.271 + struct pollfd *ioq_pollfds; 1.272 + int ioq_pollfds_size; 1.273 +#endif /* _PR_USE_POLL */ 1.274 +}; 1.275 + 1.276 +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) 1.277 +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) 1.278 +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) 1.279 +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) 1.280 +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) 1.281 +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) 1.282 +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) 1.283 +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) 1.284 +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) 1.285 +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) 1.286 +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) 1.287 +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) 1.288 +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) 1.289 + 1.290 +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 1.291 + 1.292 + 1.293 +struct _MDCPU { 1.294 + PRInt32 id; 1.295 + PRInt32 suspending_id; 1.296 + struct _MDCPU_Unix md_unix; 1.297 +}; 1.298 + 1.299 +/* 1.300 +** Initialize the thread context preparing it to execute _main. 1.301 +*/ 1.302 +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ 1.303 + PR_BEGIN_MACRO \ 1.304 + int *jb = (_thread)->md.jb; \ 1.305 + *status = PR_TRUE; \ 1.306 + (void) setjmp(jb); \ 1.307 + (_thread)->md.jb[JB_SP] = (int) ((_sp) - 64); \ 1.308 + (_thread)->md.jb[JB_PC] = (int) _main; \ 1.309 + _thread->no_sched = 0; \ 1.310 + PR_END_MACRO 1.311 + 1.312 +/* 1.313 +** Switch away from the current thread context by saving its state and 1.314 +** calling the thread scheduler. Reload cpu when we come back from the 1.315 +** context switch because it might have changed. 1.316 +* 1.317 +* XXX RUNQ lock needed before clearing _PR_NO_SCHED flag, because the 1.318 +* thread may be unr RUNQ? 1.319 +*/ 1.320 +#define _MD_SWITCH_CONTEXT(_thread) \ 1.321 + PR_BEGIN_MACRO \ 1.322 + PR_ASSERT(_thread->no_sched); \ 1.323 + if (!setjmp(_thread->md.jb)) { \ 1.324 + _MD_SAVE_ERRNO(_thread) \ 1.325 + _MD_SET_LAST_THREAD(_thread); \ 1.326 + _PR_Schedule(); \ 1.327 + } else { \ 1.328 + PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \ 1.329 + _MD_LAST_THREAD()->no_sched = 0; \ 1.330 + } \ 1.331 + PR_END_MACRO 1.332 + 1.333 +/* 1.334 +** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or 1.335 +** initialized by _MD_INIT_CONTEXT. 1.336 +*/ 1.337 +#define _MD_RESTORE_CONTEXT(_newThread) \ 1.338 + PR_BEGIN_MACRO \ 1.339 + int *jb = (_newThread)->md.jb; \ 1.340 + _MD_RESTORE_ERRNO(_newThread) \ 1.341 + _MD_SET_CURRENT_THREAD(_newThread); \ 1.342 + _newThread->no_sched = 1; \ 1.343 + longjmp(jb, 1); \ 1.344 + PR_END_MACRO 1.345 + 1.346 +NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread, 1.347 + PRBool wakeup_parent); 1.348 +NSPR_API(PRStatus) _MD_InitAttachedThread(struct PRThread *thread, 1.349 + PRBool wakeup_parent); 1.350 +#define _MD_INIT_THREAD(thread) _MD_InitThread(thread, PR_TRUE) 1.351 +#define _MD_INIT_ATTACHED_THREAD(thread) \ 1.352 + _MD_InitAttachedThread(thread, PR_FALSE) 1.353 + 1.354 +NSPR_API(void) _MD_ExitThread(struct PRThread *thread); 1.355 +#define _MD_EXIT_THREAD _MD_ExitThread 1.356 + 1.357 +NSPR_API(void) _MD_SuspendThread(struct PRThread *thread); 1.358 +#define _MD_SUSPEND_THREAD _MD_SuspendThread 1.359 + 1.360 +NSPR_API(void) _MD_ResumeThread(struct PRThread *thread); 1.361 +#define _MD_RESUME_THREAD _MD_ResumeThread 1.362 + 1.363 +NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread); 1.364 +#define _MD_SUSPEND_CPU _MD_SuspendCPU 1.365 + 1.366 +NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread); 1.367 +#define _MD_RESUME_CPU _MD_ResumeCPU 1.368 + 1.369 +#define _MD_BEGIN_SUSPEND_ALL() 1.370 +#define _MD_END_SUSPEND_ALL() 1.371 +#define _MD_BEGIN_RESUME_ALL() 1.372 +#define _MD_END_RESUME_ALL() 1.373 + 1.374 +NSPR_API(void) _MD_InitLocks(void); 1.375 +#define _MD_INIT_LOCKS _MD_InitLocks 1.376 + 1.377 +NSPR_API(void) _MD_CleanThread(struct PRThread *thread); 1.378 +#define _MD_CLEAN_THREAD _MD_CleanThread 1.379 + 1.380 +#define _MD_YIELD() sginap(0) 1.381 + 1.382 +/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and 1.383 + * awaken a thread which is waiting on a lock or cvar. 1.384 + */ 1.385 +NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout); 1.386 +#define _MD_WAIT _MD_wait 1.387 + 1.388 +NSPR_API(void) _PR_MD_primordial_cpu(); 1.389 +NSPR_API(void) _PR_MD_WAKEUP_PRIMORDIAL_CPU(); 1.390 + 1.391 +NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *); 1.392 +#define _MD_WAKEUP_WAITER _MD_WakeupWaiter 1.393 + 1.394 +NSPR_API(void ) _MD_exit(PRIntn status); 1.395 +#define _MD_EXIT _MD_exit 1.396 + 1.397 +#include "prthread.h" 1.398 + 1.399 +NSPR_API(void) _MD_SetPriority(struct _MDThread *thread, 1.400 + PRThreadPriority newPri); 1.401 +#define _MD_SET_PRIORITY _MD_SetPriority 1.402 + 1.403 +NSPR_API(PRStatus) _MD_CreateThread( 1.404 + struct PRThread *thread, 1.405 + void (*start) (void *), 1.406 + PRThreadPriority priority, 1.407 + PRThreadScope scope, 1.408 + PRThreadState state, 1.409 + PRUint32 stackSize); 1.410 +#define _MD_CREATE_THREAD _MD_CreateThread 1.411 + 1.412 +extern void _MD_CleanupBeforeExit(void); 1.413 +#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit 1.414 + 1.415 +NSPR_API(void) _PR_MD_PRE_CLEANUP(PRThread *me); 1.416 + 1.417 + 1.418 +/* The following defines the unwrapped versions of select() and poll(). */ 1.419 +extern int _select(int nfds, fd_set *readfds, fd_set *writefds, 1.420 + fd_set *exceptfds, struct timeval *timeout); 1.421 +#define _MD_SELECT _select 1.422 + 1.423 +#include <stropts.h> 1.424 +#include <poll.h> 1.425 +#define _MD_POLL _poll 1.426 +extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); 1.427 + 1.428 + 1.429 +#define HAVE_THREAD_AFFINITY 1 1.430 + 1.431 +NSPR_API(PRInt32) _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask); 1.432 +#define _MD_GETTHREADAFFINITYMASK _MD_GetThreadAffinityMask 1.433 + 1.434 +NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu); 1.435 +#define _MD_INIT_RUNNING_CPU _MD_InitRunningCPU 1.436 + 1.437 +#endif /* defined(_PR_PTHREADS) */ 1.438 + 1.439 +#endif /* _LANGUAGE_ASSEMBLY */ 1.440 + 1.441 +#endif /* nspr_irix_defs_h___ */