Changeset 101810 in vbox for trunk/src/libs/xpcom18a4/nsprpub
- Timestamp:
- Nov 5, 2023 10:10:38 AM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/nsprpub/pr
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/nsprpub/pr/include/md/_solaris.h
r101796 r101810 94 94 * 64-bit Solaris requires sparc v9, which has atomic instructions. 95 95 */ 96 #if defined(i386) || defined( _PR_GLOBAL_THREADS_ONLY) || defined(IS_64)96 #if defined(i386) || defined(IS_64) 97 97 #define _PR_HAVE_ATOMIC_OPS 98 98 #endif 99 99 100 #if defined(_PR_ GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)100 #if defined(_PR_PTHREADS) 101 101 /* 102 102 * We have assembly language implementation of atomic … … 167 167 }; 168 168 #endif 169 #if defined(_PR_ GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)169 #if defined(_PR_PTHREADS) 170 170 #define _PR_HAVE_GETHOST_R 171 171 #define _PR_HAVE_GETHOST_R_POINTER … … 180 180 #include "_iprt_atomic.h" 181 181 182 #if defined(_PR_PTHREADS)183 184 182 NSPR_API(void) _MD_EarlyInit(void); 185 183 … … 187 185 #define _MD_FINAL_INIT _PR_UnixInit 188 186 189 #elif defined(_PR_GLOBAL_THREADS_ONLY)190 191 #include "prthread.h"192 193 #include <ucontext.h>194 195 /*196 ** Iinitialization Related definitions197 */198 199 NSPR_API(void) _MD_EarlyInit(void);200 201 #define _MD_EARLY_INIT _MD_EarlyInit202 #define _MD_FINAL_INIT _PR_UnixInit203 204 #define _MD_GET_SP(threadp) threadp->md.sp205 206 /*207 ** Clean-up the thread machine dependent data structure208 */209 #define _MD_INIT_THREAD _MD_InitializeThread210 #define _MD_INIT_ATTACHED_THREAD _MD_InitializeThread211 212 NSPR_API(PRStatus) _MD_CreateThread(PRThread *thread,213 void (*start)(void *),214 PRThreadPriority priority,215 PRThreadScope scope,216 PRThreadState state,217 PRUint32 stackSize);218 #define _MD_CREATE_THREAD _MD_CreateThread219 220 #define _PR_CONTEXT_TYPE ucontext_t221 222 #define CONTEXT(_thread) (&(_thread)->md.context)223 224 #include <thread.h>225 #include <sys/lwp.h>226 #include <synch.h>227 228 extern struct PRLock *_pr_schedLock;229 230 /*231 ** Thread Local Storage232 */233 234 #define THREAD_KEY_T thread_key_t235 236 extern struct PRThread *_pr_attached_thread_tls();237 extern struct PRThread *_pr_current_thread_tls();238 extern struct _PRCPU *_pr_current_cpu_tls();239 extern struct PRThread *_pr_last_thread_tls();240 241 extern THREAD_KEY_T threadid_key;242 extern THREAD_KEY_T cpuid_key;243 extern THREAD_KEY_T last_thread_key;244 245 #define _MD_GET_ATTACHED_THREAD() _pr_attached_thread_tls()246 #define _MD_CURRENT_THREAD() _pr_current_thread_tls()247 #define _MD_CURRENT_CPU() _pr_current_cpu_tls()248 #define _MD_LAST_THREAD() _pr_last_thread_tls()249 250 #define _MD_SET_CURRENT_THREAD(newval) \251 PR_BEGIN_MACRO \252 thr_setspecific(threadid_key, (void *)newval); \253 PR_END_MACRO254 255 #define _MD_SET_CURRENT_CPU(newval) \256 PR_BEGIN_MACRO \257 thr_setspecific(cpuid_key, (void *)newval); \258 PR_END_MACRO259 260 #define _MD_SET_LAST_THREAD(newval) \261 PR_BEGIN_MACRO \262 thr_setspecific(last_thread_key, (void *)newval); \263 PR_END_MACRO264 265 #define _MD_CLEAN_THREAD(_thread) _MD_cleanup_thread(_thread)266 extern void _MD_exit_thread(PRThread *thread);267 #define _MD_EXIT_THREAD(thread) _MD_exit_thread(thread)268 269 #define _MD_SUSPEND_THREAD(thread) _MD_Suspend(thread)270 #define _MD_RESUME_THREAD(thread) thr_continue((thread)->md.handle)271 272 /* XXXX Needs to be defined - Prashant */273 #define _MD_SUSPEND_CPU(cpu)274 #define _MD_RESUME_CPU(cpu)275 276 extern void _MD_Begin_SuspendAll(void);277 extern void _MD_End_SuspendAll(void);278 extern void _MD_End_ResumeAll(void);279 #define _MD_BEGIN_SUSPEND_ALL() _MD_Begin_SuspendAll()280 #define _MD_BEGIN_RESUME_ALL()281 #define _MD_END_SUSPEND_ALL() _MD_End_SuspendAll()282 #define _MD_END_RESUME_ALL() _MD_End_ResumeAll()283 284 #define _MD_INIT_LOCKS()285 #define _MD_NEW_LOCK(md_lockp) (mutex_init(&((md_lockp)->lock),USYNC_THREAD,NULL) ? PR_FAILURE : PR_SUCCESS)286 #define _MD_FREE_LOCK(md_lockp) mutex_destroy(&((md_lockp)->lock))287 #define _MD_UNLOCK(md_lockp) mutex_unlock(&((md_lockp)->lock))288 #define _MD_TEST_AND_LOCK(md_lockp) mutex_trylock(&((md_lockp)->lock))289 struct _MDLock;290 NSPR_API(void) _MD_lock(struct _MDLock *md_lock);291 #undef PROFILE_LOCKS292 #ifndef PROFILE_LOCKS293 #define _MD_LOCK(md_lockp) _MD_lock(md_lockp)294 #else295 #define _MD_LOCK(md_lockp) \296 PR_BEGIN_MACRO \297 int rv = _MD_TEST_AND_LOCK(md_lockp); \298 if (rv == 0) { \299 (md_lockp)->hitcount++; \300 } else { \301 (md_lockp)->misscount++; \302 _MD_lock(md_lockp); \303 } \304 PR_END_MACRO305 #endif306 307 #define _PR_LOCK_HEAP() if (_pr_heapLock) _MD_LOCK(&_pr_heapLock->md)308 #define _PR_UNLOCK_HEAP() if (_pr_heapLock) _MD_UNLOCK(&_pr_heapLock->md)309 310 #define _MD_ATTACH_THREAD(threadp)311 312 313 #define THR_KEYCREATE thr_keycreate314 #define THR_SELF thr_self315 #define _MD_NEW_CV(condp) cond_init(&((condp)->cv), USYNC_THREAD, 0)316 #define COND_WAIT(condp, mutexp) cond_wait(condp, mutexp)317 #define COND_TIMEDWAIT(condp, mutexp, tspec) \318 cond_timedwait(condp, mutexp, tspec)319 #define _MD_NOTIFY_CV(condp, lockp) cond_signal(&((condp)->cv))320 #define _MD_NOTIFYALL_CV(condp,unused) cond_broadcast(&((condp)->cv))321 #define _MD_FREE_CV(condp) cond_destroy(&((condp)->cv))322 #define _MD_YIELD() thr_yield()323 #include <time.h>324 /*325 * Because clock_gettime() on Solaris/x86 2.4 always generates a326 * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),327 * which is implemented using gettimeofday().328 */329 #if defined(i386) && defined(SOLARIS2_4)330 extern int _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp);331 #define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))332 #else333 #define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))334 #endif /* i386 && SOLARIS2_4 */335 336 #define MUTEX_T mutex_t337 #define COND_T cond_t338 339 #define _MD_NEW_SEM(md_semp,_val) sema_init(&((md_semp)->sem),_val,USYNC_THREAD,NULL)340 #define _MD_DESTROY_SEM(md_semp) sema_destroy(&((md_semp)->sem))341 #define _MD_WAIT_SEM(md_semp) sema_wait(&((md_semp)->sem))342 #define _MD_POST_SEM(md_semp) sema_post(&((md_semp)->sem))343 344 #define _MD_SAVE_ERRNO(_thread)345 #define _MD_RESTORE_ERRNO(_thread)346 #define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)347 348 extern struct _MDLock _pr_ioq_lock;349 #define _MD_IOQ_LOCK() _MD_LOCK(&_pr_ioq_lock)350 #define _MD_IOQ_UNLOCK() _MD_UNLOCK(&_pr_ioq_lock)351 352 extern PRStatus _MD_wait(struct PRThread *, PRIntervalTime timeout);353 #define _MD_WAIT _MD_wait354 355 extern PRStatus _MD_WakeupWaiter(struct PRThread *);356 #define _MD_WAKEUP_WAITER _MD_WakeupWaiter357 358 NSPR_API(void) _MD_InitIO(void);359 #define _MD_INIT_IO _MD_InitIO360 361 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \362 PR_BEGIN_MACRO \363 *status = PR_TRUE; \364 PR_END_MACRO365 #define _MD_SWITCH_CONTEXT(_thread)366 #define _MD_RESTORE_CONTEXT(_newThread)367 368 struct _MDLock {369 MUTEX_T lock;370 #ifdef PROFILE_LOCKS371 PRInt32 hitcount;372 PRInt32 misscount;373 #endif374 };375 376 struct _MDCVar {377 COND_T cv;378 };379 380 struct _MDSemaphore {381 sema_t sem;382 };383 384 struct _MDThread {385 _PR_CONTEXT_TYPE context;386 thread_t handle;387 lwpid_t lwpid;388 uint_t sp; /* stack pointer */389 uint_t threadID; /* ptr to solaris-internal thread id structures */390 struct _MDSemaphore waiter_sem;391 };392 393 struct _MDThreadStack {394 PRInt8 notused;395 };396 397 struct _MDSegment {398 PRInt8 notused;399 };400 401 /*402 * md-specific cpu structure field, common to all Unix platforms403 */404 #define _PR_MD_MAX_OSFD FD_SETSIZE405 406 struct _MDCPU_Unix {407 PRCList ioQ;408 PRUint32 ioq_timeout;409 PRInt32 ioq_max_osfd;410 PRInt32 ioq_osfd_cnt;411 #ifndef _PR_USE_POLL412 fd_set fd_read_set, fd_write_set, fd_exception_set;413 PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],414 fd_exception_cnt[_PR_MD_MAX_OSFD];415 #else416 struct pollfd *ioq_pollfds;417 int ioq_pollfds_size;418 #endif /* _PR_USE_POLL */419 };420 421 #define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ)422 #define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))423 #define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set)424 #define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt)425 #define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set)426 #define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt)427 #define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set)428 #define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt)429 #define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout)430 #define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd)431 #define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt)432 #define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds)433 #define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size)434 435 #define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32436 437 438 struct _MDCPU {439 struct _MDCPU_Unix md_unix;440 };441 442 /* The following defines the unwrapped versions of select() and poll(). */443 extern int _select(int nfds, fd_set *readfds, fd_set *writefds,444 fd_set *exceptfds, struct timeval *timeout);445 #define _MD_SELECT _select446 447 #include <poll.h>448 #define _MD_POLL _poll449 extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);450 451 PR_BEGIN_EXTERN_C452 453 /*454 ** Missing function prototypes455 */456 extern int gethostname (char *name, int namelen);457 458 PR_END_EXTERN_C459 460 #else /* _PR_GLOBAL_THREADS_ONLY */461 462 /*463 * LOCAL_THREADS_ONLY implementation on Solaris464 */465 466 #include "prthread.h"467 468 #include <errno.h>469 #include <ucontext.h>470 #include <sys/stack.h>471 #include <synch.h>472 473 /*474 ** Iinitialization Related definitions475 */476 477 NSPR_API(void) _MD_EarlyInit(void);478 NSPR_API(void) _MD_SolarisInit();479 #define _MD_EARLY_INIT _MD_EarlyInit480 #define _MD_FINAL_INIT _MD_SolarisInit481 #define _MD_INIT_THREAD _MD_InitializeThread482 483 #ifdef USE_SETJMP484 485 #include <setjmp.h>486 487 #define _PR_CONTEXT_TYPE jmp_buf488 489 #ifdef sparc490 #define _MD_GET_SP(_t) (_t)->md.context[2]491 #else492 #define _MD_GET_SP(_t) (_t)->md.context[4]493 #endif494 495 #define PR_NUM_GCREGS _JBLEN496 #define CONTEXT(_thread) (_thread)->md.context497 498 #else /* ! USE_SETJMP */499 500 #ifdef sparc501 #define _PR_CONTEXT_TYPE ucontext_t502 #define _MD_GET_SP(_t) (_t)->md.context.uc_mcontext.gregs[REG_SP]503 /*504 ** Sparc's use register windows. the _MD_GetRegisters for the sparc's505 ** doesn't actually store anything into the argument buffer; instead the506 ** register windows are homed to the stack. I assume that the stack507 ** always has room for the registers to spill to...508 */509 #define PR_NUM_GCREGS 0510 #else511 #define _PR_CONTEXT_TYPE unsigned int edi; sigset_t oldMask, blockMask; ucontext_t512 #define _MD_GET_SP(_t) (_t)->md.context.uc_mcontext.gregs[USP]513 #define PR_NUM_GCREGS _JBLEN514 #endif515 516 #define CONTEXT(_thread) (&(_thread)->md.context)517 518 #endif /* ! USE_SETJMP */519 520 #include <time.h>521 /*522 * Because clock_gettime() on Solaris/x86 always generates a523 * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),524 * which is implemented using gettimeofday().525 */526 #ifdef i386527 #define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))528 #else529 #define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))530 #endif /* i386 */531 532 #define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno;533 #define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode;534 535 #ifdef sparc536 537 #ifdef USE_SETJMP538 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \539 PR_BEGIN_MACRO \540 int *context = (_thread)->md.context; \541 *status = PR_TRUE; \542 (void) setjmp(context); \543 (_thread)->md.context[1] = (int) ((_sp) - 64); \544 (_thread)->md.context[2] = (int) _main; \545 (_thread)->md.context[3] = (int) _main + 4; \546 _thread->no_sched = 0; \547 PR_END_MACRO548 549 #define _MD_SWITCH_CONTEXT(_thread) \550 if (!setjmp(CONTEXT(_thread))) { \551 _MD_SAVE_ERRNO(_thread) \552 _MD_SET_LAST_THREAD(_thread); \553 _MD_SET_CURRENT_THREAD(_thread); \554 _PR_Schedule(); \555 }556 557 #define _MD_RESTORE_CONTEXT(_newThread) \558 { \559 _MD_RESTORE_ERRNO(_newThread) \560 _MD_SET_CURRENT_THREAD(_newThread); \561 longjmp(CONTEXT(_newThread), 1); \562 }563 564 #else565 /*566 ** Initialize the thread context preparing it to execute _main.567 */568 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \569 PR_BEGIN_MACRO \570 ucontext_t *uc = CONTEXT(_thread); \571 *status = PR_TRUE; \572 getcontext(uc); \573 uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \574 uc->uc_stack.ss_size = _thread->stack->stackSize; \575 uc->uc_stack.ss_flags = 0; /* ? */ \576 uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp; \577 uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main; \578 uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4; \579 uc->uc_flags = UC_ALL; \580 _thread->no_sched = 0; \581 PR_END_MACRO582 583 /*584 ** Switch away from the current thread context by saving its state and585 ** calling the thread scheduler. Reload cpu when we come back from the586 ** context switch because it might have changed.587 */588 #define _MD_SWITCH_CONTEXT(_thread) \589 PR_BEGIN_MACRO \590 if (!getcontext(CONTEXT(_thread))) { \591 _MD_SAVE_ERRNO(_thread); \592 _MD_SET_LAST_THREAD(_thread); \593 _PR_Schedule(); \594 } \595 PR_END_MACRO596 597 /*598 ** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or599 ** initialized by _MD_INIT_CONTEXT.600 */601 #define _MD_RESTORE_CONTEXT(_newThread) \602 PR_BEGIN_MACRO \603 ucontext_t *uc = CONTEXT(_newThread); \604 uc->uc_mcontext.gregs[11] = 1; \605 _MD_RESTORE_ERRNO(_newThread); \606 _MD_SET_CURRENT_THREAD(_newThread); \607 setcontext(uc); \608 PR_END_MACRO609 #endif610 611 #else /* x86 solaris */612 613 #ifdef USE_SETJMP614 615 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \616 PR_BEGIN_MACRO \617 *status = PR_TRUE; \618 if (setjmp(CONTEXT(_thread))) _main(); \619 _MD_GET_SP(_thread) = (int) ((_sp) - 64); \620 PR_END_MACRO621 622 #define _MD_SWITCH_CONTEXT(_thread) \623 if (!setjmp(CONTEXT(_thread))) { \624 _MD_SAVE_ERRNO(_thread) \625 _PR_Schedule(); \626 }627 628 #define _MD_RESTORE_CONTEXT(_newThread) \629 { \630 _MD_RESTORE_ERRNO(_newThread) \631 _MD_SET_CURRENT_THREAD(_newThread); \632 longjmp(CONTEXT(_newThread), 1); \633 }634 635 #else /* USE_SETJMP */636 637 #define WINDOWSIZE 0638 639 int getedi(void);640 void setedi(int);641 642 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \643 PR_BEGIN_MACRO \644 ucontext_t *uc = CONTEXT(_thread); \645 *status = PR_TRUE; \646 getcontext(uc); \647 /* Force sp to be double aligned! */ \648 uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \649 uc->uc_mcontext.gregs[PC] = (int) _main; \650 (_thread)->no_sched = 0; \651 PR_END_MACRO652 653 /* getcontext() may return 1, contrary to what the man page says */654 #define _MD_SWITCH_CONTEXT(_thread) \655 PR_BEGIN_MACRO \656 ucontext_t *uc = CONTEXT(_thread); \657 PR_ASSERT(_thread->no_sched); \658 sigfillset(&((_thread)->md.blockMask)); \659 sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask), \660 &((_thread)->md.oldMask)); \661 (_thread)->md.edi = getedi(); \662 if (! getcontext(uc)) { \663 sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \664 uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi; \665 _MD_SAVE_ERRNO(_thread) \666 _MD_SET_LAST_THREAD(_thread); \667 _PR_Schedule(); \668 } else { \669 sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \670 setedi((_thread)->md.edi); \671 PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \672 _MD_LAST_THREAD()->no_sched = 0; \673 } \674 PR_END_MACRO675 676 /*677 ** Restore a thread context, saved by _PR_SWITCH_CONTEXT678 */679 #define _MD_RESTORE_CONTEXT(_newthread) \680 PR_BEGIN_MACRO \681 ucontext_t *uc = CONTEXT(_newthread); \682 uc->uc_mcontext.gregs[EAX] = 1; \683 _MD_RESTORE_ERRNO(_newthread) \684 _MD_SET_CURRENT_THREAD(_newthread); \685 (_newthread)->no_sched = 1; \686 setcontext(uc); \687 PR_END_MACRO688 #endif /* USE_SETJMP */689 690 #endif /* sparc */691 692 struct _MDLock {693 PRInt8 notused;694 };695 696 struct _MDCVar {697 PRInt8 notused;698 };699 700 struct _MDSemaphore {701 PRInt8 notused;702 };703 704 struct _MDThread {705 _PR_CONTEXT_TYPE context;706 int errcode;707 int id;708 };709 710 struct _MDThreadStack {711 PRInt8 notused;712 };713 714 struct _MDSegment {715 PRInt8 notused;716 };717 718 /*719 * md-specific cpu structure field720 */721 #define _PR_MD_MAX_OSFD FD_SETSIZE722 723 struct _MDCPU_Unix {724 PRCList ioQ;725 PRUint32 ioq_timeout;726 PRInt32 ioq_max_osfd;727 PRInt32 ioq_osfd_cnt;728 #ifndef _PR_USE_POLL729 fd_set fd_read_set, fd_write_set, fd_exception_set;730 PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],731 fd_exception_cnt[_PR_MD_MAX_OSFD];732 #else733 struct pollfd *ioq_pollfds;734 int ioq_pollfds_size;735 #endif /* _PR_USE_POLL */736 };737 738 #define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ)739 #define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))740 #define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set)741 #define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt)742 #define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set)743 #define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt)744 #define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set)745 #define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt)746 #define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout)747 #define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd)748 #define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt)749 #define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds)750 #define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size)751 752 #define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32753 754 struct _MDCPU {755 struct _MDCPU_Unix md_unix;756 };757 758 #ifndef _PR_PTHREADS759 #define _MD_INIT_LOCKS()760 #endif761 #define _MD_NEW_LOCK(lock) PR_SUCCESS762 #define _MD_FREE_LOCK(lock)763 #define _MD_LOCK(lock)764 #define _MD_UNLOCK(lock)765 #define _MD_INIT_IO()766 #define _MD_IOQ_LOCK()767 #define _MD_IOQ_UNLOCK()768 769 #define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)770 #define _MD_INIT_THREAD _MD_InitializeThread771 #define _MD_EXIT_THREAD(thread)772 #define _MD_SUSPEND_THREAD(thread)773 #define _MD_RESUME_THREAD(thread)774 #define _MD_CLEAN_THREAD(_thread)775 776 extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout);777 extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *);778 extern void _MD_YIELD(void);779 extern PRStatus _MD_InitializeThread(PRThread *thread);780 extern void _MD_SET_PRIORITY(struct _MDThread *thread,781 PRThreadPriority newPri);782 extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *),783 PRThreadPriority priority, PRThreadScope scope, PRThreadState state,784 PRUint32 stackSize);785 786 NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);787 #define _MD_GET_INTERVAL _MD_Solaris_GetInterval788 NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);789 #define _MD_INTERVAL_PER_SEC _MD_Solaris_TicksPerSecond790 791 /* The following defines the unwrapped versions of select() and poll(). */792 extern int _select(int nfds, fd_set *readfds, fd_set *writefds,793 fd_set *exceptfds, struct timeval *timeout);794 #define _MD_SELECT _select795 796 #include <stropts.h>797 #include <poll.h>798 #define _MD_POLL _poll799 extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);800 801 PR_BEGIN_EXTERN_C802 803 /*804 ** Missing function prototypes805 */806 extern int gethostname (char *name, int namelen);807 808 PR_END_EXTERN_C809 810 #endif /* _PR_GLOBAL_THREADS_ONLY */811 812 187 extern void _MD_solaris_map_sendfile_error(int err); 813 188 -
trunk/src/libs/xpcom18a4/nsprpub/pr/include/md/_unixos.h
r101749 r101810 137 137 PRIntervalTime timeout); 138 138 extern void _PR_Unblock_IO_Wait(struct PRThread *thr); 139 140 #if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)141 #define _MD_CHECK_FOR_EXIT()142 #endif143 139 144 140 extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set; … … 289 285 290 286 #define _MD_PAUSE_CPU _MD_PauseCPU 291 292 #if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)293 #define _MD_CLEANUP_BEFORE_EXIT()294 #endif295 287 296 288 #ifndef IRIX -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/solaris.c
r101805 r101810 85 85 } 86 86 87 #if !defined(i386) && !defined(IS_64)88 #if defined(_PR_HAVE_ATOMIC_OPS)89 /* NOTE:90 * SPARC v9 (Ultras) do have an atomic test-and-set operation. But91 * SPARC v8 doesn't. We should detect in the init if we are running on92 * v8 or v9, and then use assembly where we can.93 *94 * This code uses the Solaris threads API. It can be used in both the95 * pthreads and Solaris threads versions of nspr20 because "POSIX threads96 * and Solaris threads are fully compatible even within the same process",97 * to quote from pthread_create(3T).98 */99 100 #include <thread.h>101 #include <synch.h>102 103 static mutex_t _solaris_atomic = DEFAULTMUTEX;104 105 PRInt32106 _MD_AtomicIncrement(PRInt32 *val)107 {108 PRInt32 rv;109 if (mutex_lock(&_solaris_atomic) != 0)110 PR_ASSERT(0);111 112 rv = ++(*val);113 114 if (mutex_unlock(&_solaris_atomic) != 0)\115 PR_ASSERT(0);116 117 return rv;118 }119 120 PRInt32121 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)122 {123 PRInt32 rv;124 if (mutex_lock(&_solaris_atomic) != 0)125 PR_ASSERT(0);126 127 rv = ((*ptr) += val);128 129 if (mutex_unlock(&_solaris_atomic) != 0)\130 PR_ASSERT(0);131 132 return rv;133 }134 135 PRInt32136 _MD_AtomicDecrement(PRInt32 *val)137 {138 PRInt32 rv;139 if (mutex_lock(&_solaris_atomic) != 0)140 PR_ASSERT(0);141 142 rv = --(*val);143 144 if (mutex_unlock(&_solaris_atomic) != 0)\145 PR_ASSERT(0);146 147 return rv;148 }149 150 PRInt32151 _MD_AtomicSet(PRInt32 *val, PRInt32 newval)152 {153 PRInt32 rv;154 if (mutex_lock(&_solaris_atomic) != 0)155 PR_ASSERT(0);156 157 rv = *val;158 *val = newval;159 160 if (mutex_unlock(&_solaris_atomic) != 0)\161 PR_ASSERT(0);162 163 return rv;164 }165 #endif /* _PR_HAVE_ATOMIC_OPS */166 #endif /* !defined(i386) */167 168 #if defined(_PR_GLOBAL_THREADS_ONLY)169 #include <signal.h>170 #include <errno.h>171 #include <fcntl.h>172 #include <thread.h>173 174 #include <sys/lwp.h>175 #include <sys/procfs.h>176 #include <sys/syscall.h>177 extern int syscall(); /* not declared in sys/syscall.h */178 179 static sigset_t old_mask; /* store away original gc thread sigmask */180 static PRIntn gcprio; /* store away original gc thread priority */181 182 THREAD_KEY_T threadid_key;183 THREAD_KEY_T cpuid_key;184 THREAD_KEY_T last_thread_key;185 static sigset_t set, oldset;186 187 static void188 threadid_key_destructor(void *value)189 {190 PRThread *me = (PRThread *)value;191 PR_ASSERT(me != NULL);192 /* the thread could be PRIMORDIAL (thus not ATTACHED) */193 if (me->flags & _PR_ATTACHED) {194 /*195 * The Solaris thread library sets the thread specific196 * data (the current thread) to NULL before invoking197 * the destructor. We need to restore it to prevent the198 * _PR_MD_CURRENT_THREAD() call in _PRI_DetachThread()199 * from attaching the thread again.200 */201 _PR_MD_SET_CURRENT_THREAD(me);202 _PRI_DetachThread();203 }204 }205 206 void _MD_EarlyInit(void)207 {208 THR_KEYCREATE(&threadid_key, threadid_key_destructor);209 THR_KEYCREATE(&cpuid_key, NULL);210 THR_KEYCREATE(&last_thread_key, NULL);211 sigemptyset(&set);212 sigaddset(&set, SIGALRM);213 }214 215 PRStatus _MD_CreateThread(PRThread *thread,216 void (*start)(void *),217 PRThreadPriority priority,218 PRThreadScope scope,219 PRThreadState state,220 PRUint32 stackSize)221 {222 PRInt32 flags;223 224 /* mask out SIGALRM for native thread creation */225 thr_sigsetmask(SIG_BLOCK, &set, &oldset);226 227 /*228 * Note that we create joinable threads with the THR_DETACHED229 * flag. The reasons why we don't use thr_join to implement230 * PR_JoinThread are:231 * - We use a termination condition variable in the PRThread232 * structure to implement PR_JoinThread across all classic233 * nspr implementation strategies.234 * - The native threads may be recycled by NSPR to run other235 * new NSPR threads, so the native threads may not terminate236 * when the corresponding NSPR threads terminate.237 */238 flags = THR_SUSPENDED|THR_DETACHED;239 if (_PR_IS_GCABLE_THREAD(thread) || (thread->flags & _PR_BOUND_THREAD) ||240 (scope == PR_GLOBAL_BOUND_THREAD))241 flags |= THR_BOUND;242 243 if (thr_create(NULL, thread->stack->stackSize,244 (void *(*)(void *)) start, (void *) thread,245 flags,246 &thread->md.handle)) {247 thr_sigsetmask(SIG_SETMASK, &oldset, NULL);248 return PR_FAILURE;249 }250 251 /* When the thread starts running, then the lwpid is set to the right252 * value. Until then we want to mark this as 'uninit' so that253 * its register state is initialized properly for GC */254 255 thread->md.lwpid = -1;256 thr_sigsetmask(SIG_SETMASK, &oldset, NULL);257 _MD_NEW_SEM(&thread->md.waiter_sem, 0);258 259 if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) {260 thread->flags |= _PR_GLOBAL_SCOPE;261 }262 263 _MD_SET_PRIORITY(&(thread->md), priority);264 265 /* Activate the thread */266 if (thr_continue( thread->md.handle ) ) {267 return PR_FAILURE;268 }269 return PR_SUCCESS;270 }271 272 void _MD_cleanup_thread(PRThread *thread)273 {274 thread_t hdl;275 276 hdl = thread->md.handle;277 278 /*279 ** First, suspend the thread (unless it's the active one)280 ** Because we suspend it first, we don't have to use LOCK_SCHEDULER to281 ** prevent both of us modifying the thread structure at the same time.282 */283 if ( thread != _PR_MD_CURRENT_THREAD() ) {284 thr_suspend(hdl);285 }286 PR_LOG(_pr_thread_lm, PR_LOG_MIN,287 ("(0X%x)[DestroyThread]\n", thread));288 289 _MD_DESTROY_SEM(&thread->md.waiter_sem);290 }291 292 void _MD_exit_thread(PRThread *thread)293 {294 _MD_CLEAN_THREAD(thread);295 _MD_SET_CURRENT_THREAD(NULL);296 }297 298 void _MD_SET_PRIORITY(_MDThread *md_thread,299 PRThreadPriority newPri)300 {301 PRIntn nativePri;302 303 if (newPri < PR_PRIORITY_FIRST) {304 newPri = PR_PRIORITY_FIRST;305 } else if (newPri > PR_PRIORITY_LAST) {306 newPri = PR_PRIORITY_LAST;307 }308 /* Solaris priorities are from 0 to 127 */309 nativePri = newPri * 127 / PR_PRIORITY_LAST;310 if(thr_setprio((thread_t)md_thread->handle, nativePri)) {311 PR_LOG(_pr_thread_lm, PR_LOG_MIN,312 ("_PR_SetThreadPriority: can't set thread priority\n"));313 }314 }315 316 void _MD_WAIT_CV(317 struct _MDCVar *md_cv, struct _MDLock *md_lock, PRIntervalTime timeout)318 {319 struct timespec tt;320 PRUint32 msec;321 PRThread *me = _PR_MD_CURRENT_THREAD();322 323 PR_ASSERT((!suspendAllOn) || (suspendAllThread != me));324 325 if (PR_INTERVAL_NO_TIMEOUT == timeout) {326 COND_WAIT(&md_cv->cv, &md_lock->lock);327 } else {328 msec = PR_IntervalToMilliseconds(timeout);329 330 GETTIME(&tt);331 tt.tv_sec += msec / PR_MSEC_PER_SEC;332 tt.tv_nsec += (msec % PR_MSEC_PER_SEC) * PR_NSEC_PER_MSEC;333 /* Check for nsec overflow - otherwise we'll get an EINVAL */334 if (tt.tv_nsec >= PR_NSEC_PER_SEC) {335 tt.tv_sec++;336 tt.tv_nsec -= PR_NSEC_PER_SEC;337 }338 COND_TIMEDWAIT(&md_cv->cv, &md_lock->lock, &tt);339 }340 }341 342 void _MD_lock(struct _MDLock *md_lock)343 {344 #ifdef DEBUG345 /* This code was used for GC testing to make sure that we didn't attempt346 * to grab any locks while threads are suspended.347 */348 PRLock *lock;349 350 if ((suspendAllOn) && (suspendAllThread == _PR_MD_CURRENT_THREAD())) {351 lock = ((PRLock *) ((char*) (md_lock) - offsetof(PRLock,ilock)));352 PR_ASSERT(lock->owner == NULL);353 return;354 }355 #endif /* DEBUG */356 357 mutex_lock(&md_lock->lock);358 }359 360 PRThread *_pr_attached_thread_tls()361 {362 PRThread *ret;363 364 thr_getspecific(threadid_key, (void **)&ret);365 return ret;366 }367 368 PRThread *_pr_current_thread_tls()369 {370 PRThread *thread;371 372 thread = _MD_GET_ATTACHED_THREAD();373 374 if (NULL == thread) {375 thread = _PRI_AttachThread(376 PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);377 }378 PR_ASSERT(thread != NULL);379 380 return thread;381 }382 383 PRStatus384 _MD_wait(PRThread *thread, PRIntervalTime ticks)385 {386 _MD_WAIT_SEM(&thread->md.waiter_sem);387 return PR_SUCCESS;388 }389 390 PRStatus391 _MD_WakeupWaiter(PRThread *thread)392 {393 if (thread == NULL) {394 return PR_SUCCESS;395 }396 _MD_POST_SEM(&thread->md.waiter_sem);397 return PR_SUCCESS;398 }399 400 _PRCPU *_pr_current_cpu_tls()401 {402 _PRCPU *ret;403 404 thr_getspecific(cpuid_key, (void **)&ret);405 return ret;406 }407 408 PRThread *_pr_last_thread_tls()409 {410 PRThread *ret;411 412 thr_getspecific(last_thread_key, (void **)&ret);413 return ret;414 }415 416 _MDLock _pr_ioq_lock;417 418 void419 _MD_InitIO(void)420 {421 _MD_NEW_LOCK(&_pr_ioq_lock);422 }423 424 PRStatus _MD_InitializeThread(PRThread *thread)425 {426 if (!_PR_IS_NATIVE_THREAD(thread))427 return PR_SUCCESS;428 /* sol_curthread is an asm routine which grabs GR7; GR7 stores an internal429 * thread structure ptr used by solaris. We'll use this ptr later430 * with suspend/resume to find which threads are running on LWPs.431 */432 thread->md.threadID = sol_curthread();433 /* prime the sp; substract 4 so we don't hit the assert that434 * curr sp > base_stack435 */436 thread->md.sp = (uint_t) thread->stack->allocBase - sizeof(long);437 thread->md.lwpid = _lwp_self();438 thread->md.handle = THR_SELF();439 440 /* all threads on Solaris are global threads from NSPR's perspective441 * since all of them are mapped to Solaris threads.442 */443 thread->flags |= _PR_GLOBAL_SCOPE;444 445 /* For primordial/attached thread, we don't create an underlying native thread.446 * So, _MD_CREATE_THREAD() does not get called. We need to do initialization447 * like allocating thread's synchronization variables and set the underlying448 * native thread's priority.449 */450 if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {451 _MD_NEW_SEM(&thread->md.waiter_sem, 0);452 _MD_SET_PRIORITY(&(thread->md), thread->priority);453 }454 return PR_SUCCESS;455 }456 457 /* Sleep for n milliseconds, n < 1000 */458 void solaris_msec_sleep(int n)459 {460 struct timespec ts;461 462 ts.tv_sec = 0;463 ts.tv_nsec = 1000000*n;464 if (syscall(SYS_nanosleep, &ts, 0, 0) < 0) {465 PR_ASSERT(0);466 }467 }468 469 #define VALID_SP(sp, bottom, top) \470 (((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top)))471 472 void solaris_record_regs(PRThread *t, prstatus_t *lwpstatus)473 {474 #ifdef sparc475 long *regs = (long *)&t->md.context.uc_mcontext.gregs[0];476 477 PR_ASSERT(_PR_IS_GCABLE_THREAD(t));478 PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[REG_G7]);479 480 t->md.sp = lwpstatus->pr_reg[REG_SP];481 PR_ASSERT(VALID_SP(t->md.sp, t->stack->stackBottom, t->stack->stackTop));482 483 regs[0] = lwpstatus->pr_reg[R_G1];484 regs[1] = lwpstatus->pr_reg[R_G2];485 regs[2] = lwpstatus->pr_reg[R_G3];486 regs[3] = lwpstatus->pr_reg[R_G4];487 regs[4] = lwpstatus->pr_reg[R_O0];488 regs[5] = lwpstatus->pr_reg[R_O1];489 regs[6] = lwpstatus->pr_reg[R_O2];490 regs[7] = lwpstatus->pr_reg[R_O3];491 regs[8] = lwpstatus->pr_reg[R_O4];492 regs[9] = lwpstatus->pr_reg[R_O5];493 regs[10] = lwpstatus->pr_reg[R_O6];494 regs[11] = lwpstatus->pr_reg[R_O7];495 #elif defined(i386)496 /*497 * To be implemented and tested498 */499 PR_ASSERT(0);500 PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[GS]);501 t->md.sp = lwpstatus->pr_reg[UESP];502 #endif503 }504 505 void solaris_preempt_off()506 {507 sigset_t set;508 509 (void)sigfillset(&set);510 syscall(SYS_sigprocmask, SIG_SETMASK, &set, &old_mask);511 }512 513 void solaris_preempt_on()514 {515 syscall(SYS_sigprocmask, SIG_SETMASK, &old_mask, NULL);516 }517 518 int solaris_open_main_proc_fd()519 {520 char buf[30];521 int fd;522 523 /* Not locked, so must be created while threads coming up */524 PR_snprintf(buf, sizeof(buf), "/proc/%ld", getpid());525 if ( (fd = syscall(SYS_open, buf, O_RDONLY)) < 0) {526 return -1;527 }528 return fd;529 }530 531 /* Return a file descriptor for the /proc entry corresponding to the532 * given lwp.533 */534 int solaris_open_lwp(lwpid_t id, int lwp_main_proc_fd)535 {536 int result;537 538 if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCOPENLWP, &id)) <0)539 return -1; /* exited??? */540 541 return result;542 }543 void _MD_Begin_SuspendAll()544 {545 solaris_preempt_off();546 547 PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n"));548 /* run at highest prio so I cannot be preempted */549 thr_getprio(thr_self(), &gcprio);550 thr_setprio(thr_self(), 0x7fffffff);551 suspendAllOn = PR_TRUE;552 suspendAllThread = _PR_MD_CURRENT_THREAD();553 }554 555 void _MD_End_SuspendAll()556 {557 }558 559 void _MD_End_ResumeAll()560 {561 PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n"));562 thr_setprio(thr_self(), gcprio);563 solaris_preempt_on();564 suspendAllThread = NULL;565 suspendAllOn = PR_FALSE;566 }567 568 void _MD_Suspend(PRThread *thr)569 {570 int lwp_fd, result;571 prstatus_t lwpstatus;572 int lwp_main_proc_fd = 0;573 574 if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){575 /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend576 * during that time we can't call any thread lib or libc calls. Hence577 * make sure that no suspension is requested for Non gcable thread578 * during suspendAllOn */579 PR_ASSERT(!suspendAllOn);580 thr_suspend(thr->md.handle);581 return;582 }583 584 /* XXX Primordial thread can't be bound to an lwp, hence there is no585 * way we can assume that we can get the lwp status for primordial586 * thread reliably. Hence we skip this for primordial thread, hoping587 * that the SP is saved during lock and cond. wait.588 * XXX - Again this is concern only for java interpreter, not for the589 * server, 'cause primordial thread in the server does not do java work590 */591 if (thr->flags & _PR_PRIMORDIAL)592 return;593 594 /* XXX Important Note: If the start function of a thread is not called,595 * lwpid is -1. Then, skip this thread. This thread will get caught596 * in PR_NativeRunThread before calling the start function, because597 * we hold the pr_activeLock during suspend/resume */598 599 /* if the thread is not started yet then don't do anything */600 if (!suspendAllOn || thr->md.lwpid == -1)601 return;602 603 if (_lwp_suspend(thr->md.lwpid) < 0) {604 PR_ASSERT(0);605 return;606 }607 608 if ( (lwp_main_proc_fd = solaris_open_main_proc_fd()) < 0) {609 PR_ASSERT(0);610 return; /* XXXMB ARGH, we're hosed! */611 }612 613 if ( (lwp_fd = solaris_open_lwp(thr->md.lwpid, lwp_main_proc_fd)) < 0) {614 PR_ASSERT(0);615 close(lwp_main_proc_fd);616 return;617 }618 if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {619 /* Hopefully the thread just died... */620 close(lwp_fd);621 close(lwp_main_proc_fd);622 return;623 }624 while ( !(lwpstatus.pr_flags & PR_STOPPED) ) {625 if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {626 PR_ASSERT(0); /* ARGH SOMETHING WRONG! */627 break;628 }629 solaris_msec_sleep(1);630 }631 solaris_record_regs(thr, &lwpstatus);632 close(lwp_fd);633 close(lwp_main_proc_fd);634 }635 636 #ifdef USE_SETJMP637 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)638 {639 if (isCurrent) {640 (void) setjmp(CONTEXT(t));641 }642 *np = sizeof(CONTEXT(t)) / sizeof(PRWord);643 return (PRWord *) CONTEXT(t);644 }645 #else646 PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)647 {648 if (isCurrent) {649 (void) getcontext(CONTEXT(t));650 }651 *np = NGREG;652 return (PRWord*) &t->md.context.uc_mcontext.gregs[0];653 }654 #endif /* USE_SETJMP */655 656 #else /* _PR_GLOBAL_THREADS_ONLY */657 658 #if defined(_PR_LOCAL_THREADS_ONLY)659 660 void _MD_EarlyInit(void)661 {662 }663 664 void _MD_SolarisInit()665 {666 _PR_UnixInit();667 }668 669 void670 _MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)671 {672 return;673 }674 675 PRStatus676 _MD_InitializeThread(PRThread *thread)677 {678 return PR_SUCCESS;679 }680 681 PRStatus682 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)683 {684 PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));685 _PR_MD_SWITCH_CONTEXT(thread);686 return PR_SUCCESS;687 }688 689 PRStatus690 _MD_WAKEUP_WAITER(PRThread *thread)691 {692 PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE)));693 return PR_SUCCESS;694 }695 696 /* These functions should not be called for Solaris */697 void698 _MD_YIELD(void)699 {700 PR_NOT_REACHED("_MD_YIELD should not be called for Solaris");701 }702 703 PRStatus704 _MD_CREATE_THREAD(705 PRThread *thread,706 void (*start) (void *),707 PRThreadPriority priority,708 PRThreadScope scope,709 PRThreadState state,710 PRUint32 stackSize)711 {712 PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris");713 return(PR_FAILURE);714 }715 716 #ifdef USE_SETJMP717 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)718 {719 if (isCurrent) {720 (void) setjmp(CONTEXT(t));721 }722 *np = sizeof(CONTEXT(t)) / sizeof(PRWord);723 return (PRWord *) CONTEXT(t);724 }725 #else726 PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)727 {728 if (isCurrent) {729 (void) getcontext(CONTEXT(t));730 }731 *np = NGREG;732 return (PRWord*) &t->md.context.uc_mcontext.gregs[0];733 }734 #endif /* USE_SETJMP */735 736 #endif /* _PR_LOCAL_THREADS_ONLY */737 738 #endif /* _PR_GLOBAL_THREADS_ONLY */ -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/uxproces.c
r80569 r101810 113 113 */ 114 114 115 #if defined(_PR_GLOBAL_THREADS_ONLY) \ 116 || (defined(_PR_PTHREADS) && !defined(LINUX)) 115 #if defined(_PR_PTHREADS) && !defined(LINUX) 117 116 #define _PR_NATIVE_THREADS 118 117 #endif -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/misc/prenv.c
r2384 r101810 45 45 #define _PR_LOCK_ENV() 46 46 #define _PR_UNLOCK_ENV() 47 #elif defined(_PR_LOCAL_THREADS_ONLY)48 extern _PRCPU * _pr_primordialCPU;49 static PRIntn _is;50 #define _PR_NEW_LOCK_ENV()51 #define _PR_DELETE_LOCK_ENV()52 #define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is);53 #define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is);54 47 #else 55 48 static PRLock *_pr_envLock = NULL; -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/threads/prcmon.c
r28971 r101810 47 47 #define _PR_UNLOCK_MCACHE() 48 48 #else 49 #ifdef _PR_LOCAL_THREADS_ONLY50 #define _PR_NEW_LOCK_MCACHE()51 #define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is)52 #define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); }53 #else54 49 PRLock *_pr_mcacheLock; 55 50 #define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock()) 56 51 #define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock) 57 52 #define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock) 58 #endif59 53 #endif 60 54
Note:
See TracChangeset
for help on using the changeset viewer.