VirtualBox

Ignore:
Timestamp:
Nov 5, 2023 10:10:38 AM (15 months ago)
Author:
vboxsync
Message:

libs/xpcom: Get rid of unused code for the _PR_LOCAL_THREADS_ONLY and _PR_GLOBAL_THREADS_ONLY cases which we never use, bugref:10545

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  
    9494 * 64-bit Solaris requires sparc v9, which has atomic instructions.
    9595 */
    96 #if defined(i386) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(IS_64)
     96#if defined(i386) || defined(IS_64)
    9797#define _PR_HAVE_ATOMIC_OPS
    9898#endif
    9999
    100 #if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)
     100#if defined(_PR_PTHREADS)
    101101/*
    102102 * We have assembly language implementation of atomic
     
    167167};
    168168#endif
    169 #if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)
     169#if defined(_PR_PTHREADS)
    170170#define _PR_HAVE_GETHOST_R
    171171#define _PR_HAVE_GETHOST_R_POINTER
     
    180180#include "_iprt_atomic.h"
    181181
    182 #if defined(_PR_PTHREADS)
    183 
    184182NSPR_API(void)          _MD_EarlyInit(void);
    185183
     
    187185#define _MD_FINAL_INIT          _PR_UnixInit
    188186
    189 #elif defined(_PR_GLOBAL_THREADS_ONLY)
    190 
    191 #include "prthread.h"
    192 
    193 #include <ucontext.h>
    194 
    195 /*
    196 ** Iinitialization Related definitions
    197 */
    198 
    199 NSPR_API(void)          _MD_EarlyInit(void);
    200 
    201 #define _MD_EARLY_INIT          _MD_EarlyInit
    202 #define _MD_FINAL_INIT          _PR_UnixInit
    203 
    204 #define _MD_GET_SP(threadp)     threadp->md.sp
    205 
    206 /*
    207 ** Clean-up the thread machine dependent data structure
    208 */
    209 #define _MD_INIT_THREAD                         _MD_InitializeThread
    210 #define _MD_INIT_ATTACHED_THREAD        _MD_InitializeThread
    211 
    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_CreateThread
    219 
    220 #define _PR_CONTEXT_TYPE        ucontext_t
    221 
    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 Storage
    232 */
    233 
    234 #define THREAD_KEY_T thread_key_t
    235 
    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_MACRO
    254 
    255 #define _MD_SET_CURRENT_CPU(newval)                     \
    256         PR_BEGIN_MACRO                                  \
    257         thr_setspecific(cpuid_key, (void *)newval);     \
    258         PR_END_MACRO
    259 
    260 #define _MD_SET_LAST_THREAD(newval)                             \
    261         PR_BEGIN_MACRO                                          \
    262         thr_setspecific(last_thread_key, (void *)newval);       \
    263         PR_END_MACRO
    264        
    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_LOCKS
    292 #ifndef PROFILE_LOCKS
    293 #define _MD_LOCK(md_lockp) _MD_lock(md_lockp)
    294 #else
    295 #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_MACRO
    305 #endif
    306 
    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_keycreate
    314 #define THR_SELF thr_self
    315 #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 a
    326  * 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 #else
    333 #define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
    334 #endif  /* i386 && SOLARIS2_4 */
    335 
    336 #define MUTEX_T mutex_t
    337 #define COND_T cond_t
    338 
    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_wait
    354 
    355 extern PRStatus _MD_WakeupWaiter(struct PRThread *);
    356 #define _MD_WAKEUP_WAITER _MD_WakeupWaiter
    357 
    358 NSPR_API(void) _MD_InitIO(void);
    359 #define _MD_INIT_IO _MD_InitIO
    360 
    361 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
    362     PR_BEGIN_MACRO \
    363     *status = PR_TRUE; \
    364     PR_END_MACRO
    365 #define _MD_SWITCH_CONTEXT(_thread)
    366 #define _MD_RESTORE_CONTEXT(_newThread)
    367 
    368 struct _MDLock {
    369     MUTEX_T lock;
    370 #ifdef PROFILE_LOCKS
    371     PRInt32 hitcount;
    372     PRInt32 misscount;
    373 #endif
    374 };
    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 platforms
    403  */
    404 #define _PR_MD_MAX_OSFD FD_SETSIZE
    405 
    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_POLL
    412     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 #else
    416         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)  32
    436 
    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      _select
    446 
    447 #include <poll.h>
    448 #define _MD_POLL _poll
    449 extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
    450 
    451 PR_BEGIN_EXTERN_C
    452 
    453 /*
    454 ** Missing function prototypes
    455 */
    456 extern int gethostname (char *name, int namelen);
    457 
    458 PR_END_EXTERN_C
    459 
    460 #else /* _PR_GLOBAL_THREADS_ONLY */
    461 
    462 /*
    463  * LOCAL_THREADS_ONLY implementation on Solaris
    464  */
    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 definitions
    475 */
    476 
    477 NSPR_API(void)                          _MD_EarlyInit(void);
    478 NSPR_API(void)                          _MD_SolarisInit();
    479 #define _MD_EARLY_INIT          _MD_EarlyInit
    480 #define _MD_FINAL_INIT          _MD_SolarisInit
    481 #define _MD_INIT_THREAD         _MD_InitializeThread
    482 
    483 #ifdef USE_SETJMP
    484 
    485 #include <setjmp.h>
    486 
    487 #define _PR_CONTEXT_TYPE        jmp_buf
    488 
    489 #ifdef sparc
    490 #define _MD_GET_SP(_t)          (_t)->md.context[2]
    491 #else
    492 #define _MD_GET_SP(_t)          (_t)->md.context[4]
    493 #endif
    494 
    495 #define PR_NUM_GCREGS           _JBLEN
    496 #define CONTEXT(_thread)        (_thread)->md.context
    497 
    498 #else  /* ! USE_SETJMP */
    499 
    500 #ifdef sparc
    501 #define _PR_CONTEXT_TYPE        ucontext_t
    502 #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's
    505 ** doesn't actually store anything into the argument buffer; instead the
    506 ** register windows are homed to the stack. I assume that the stack
    507 ** always has room for the registers to spill to...
    508 */
    509 #define PR_NUM_GCREGS           0
    510 #else
    511 #define _PR_CONTEXT_TYPE        unsigned int edi; sigset_t oldMask, blockMask; ucontext_t
    512 #define _MD_GET_SP(_t)          (_t)->md.context.uc_mcontext.gregs[USP]
    513 #define PR_NUM_GCREGS           _JBLEN
    514 #endif
    515 
    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 a
    523  * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
    524  * which is implemented using gettimeofday().
    525  */
    526 #ifdef i386
    527 #define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
    528 #else
    529 #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 sparc
    536 
    537 #ifdef USE_SETJMP
    538 #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_MACRO
    548 
    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 #else
    565 /*
    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_MACRO
    582 
    583 /*
    584 ** Switch away from the current thread context by saving its state and
    585 ** calling the thread scheduler. Reload cpu when we come back from the
    586 ** 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_MACRO
    596 
    597 /*
    598 ** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
    599 ** 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_MACRO
    609 #endif
    610 
    611 #else  /* x86 solaris */
    612 
    613 #ifdef USE_SETJMP
    614 
    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_MACRO
    621 
    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              0
    638  
    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_MACRO
    652 
    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_MACRO
    675 
    676 /*
    677 ** Restore a thread context, saved by _PR_SWITCH_CONTEXT
    678 */
    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_MACRO
    688 #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 field
    720  */
    721 #define _PR_MD_MAX_OSFD FD_SETSIZE
    722 
    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_POLL
    729     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 #else
    733         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)  32
    753 
    754 struct _MDCPU {
    755         struct _MDCPU_Unix md_unix;
    756 };
    757 
    758 #ifndef _PR_PTHREADS
    759 #define _MD_INIT_LOCKS()
    760 #endif
    761 #define _MD_NEW_LOCK(lock)                              PR_SUCCESS
    762 #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_InitializeThread
    771 #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_GetInterval
    788 NSPR_API(PRIntervalTime)                                _MD_Solaris_TicksPerSecond(void);
    789 #define _MD_INTERVAL_PER_SEC                    _MD_Solaris_TicksPerSecond
    790 
    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      _select
    795 
    796 #include <stropts.h>
    797 #include <poll.h>
    798 #define _MD_POLL _poll
    799 extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
    800 
    801 PR_BEGIN_EXTERN_C
    802 
    803 /*
    804 ** Missing function prototypes
    805 */
    806 extern int gethostname (char *name, int namelen);
    807 
    808 PR_END_EXTERN_C
    809 
    810 #endif /* _PR_GLOBAL_THREADS_ONLY */
    811 
    812187extern void _MD_solaris_map_sendfile_error(int err);
    813188
  • trunk/src/libs/xpcom18a4/nsprpub/pr/include/md/_unixos.h

    r101749 r101810  
    137137    PRIntervalTime timeout);
    138138extern 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 #endif
    143139
    144140extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set;
     
    289285
    290286#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 #endif
    295287
    296288#ifndef IRIX
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/unix/solaris.c

    r101805 r101810  
    8585}
    8686
    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.  But
    91  * SPARC v8 doesn't.  We should detect in the init if we are running on
    92  * 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 the
    95  * pthreads and Solaris threads versions of nspr20 because "POSIX threads
    96  * 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 PRInt32
    106 _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 PRInt32
    121 _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 PRInt32
    136 _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 PRInt32
    151 _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 void
    188 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 specific
    196          * data (the current thread) to NULL before invoking
    197          * the destructor.  We need to restore it to prevent the
    198          * _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_DETACHED
    229      * flag.  The reasons why we don't use thr_join to implement
    230      * PR_JoinThread are:
    231      * - We use a termination condition variable in the PRThread
    232      *   structure to implement PR_JoinThread across all classic
    233      *   nspr implementation strategies.
    234      * - The native threads may be recycled by NSPR to run other
    235      *   new NSPR threads, so the native threads may not terminate
    236      *   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 right
    252      * value. Until then we want to mark this as 'uninit' so that
    253      * 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 to
    281     ** 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 DEBUG
    345     /* This code was used for GC testing to make sure that we didn't attempt
    346      * 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 PRStatus
    384 _MD_wait(PRThread *thread, PRIntervalTime ticks)
    385 {
    386         _MD_WAIT_SEM(&thread->md.waiter_sem);
    387         return PR_SUCCESS;
    388 }
    389 
    390 PRStatus
    391 _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 void
    419 _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 internal
    429      * thread structure ptr used by solaris.  We'll use this ptr later
    430      * 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 that
    434                  * curr sp > base_stack
    435                  */
    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 perspective
    441          * 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 initialization
    447          * like allocating thread's synchronization variables and set the underlying
    448          * 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 sparc
    475         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 tested
    498          */
    499         PR_ASSERT(0);
    500         PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[GS]);
    501         t->md.sp = lwpstatus->pr_reg[UESP];
    502 #endif
    503 }   
    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 the
    532  * 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_suspend
    576       * during that time we can't call any thread lib or libc calls. Hence
    577       * make sure that no suspension is requested for Non gcable thread
    578       * 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 no
    585      * way we can assume that we can get the lwp status for primordial
    586      * thread reliably. Hence we skip this for primordial thread, hoping
    587      * that the SP is saved during lock and cond. wait.
    588      * XXX - Again this is concern only for java interpreter, not for the
    589      * server, 'cause primordial thread in the server does not do java work
    590      */
    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 caught
    596      * in PR_NativeRunThread before calling the start function, because
    597      * 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_SETJMP
    637 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 #else
    646 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 void
    670 _MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
    671 {
    672     return;
    673 }
    674 
    675 PRStatus
    676 _MD_InitializeThread(PRThread *thread)
    677 {
    678         return PR_SUCCESS;
    679 }
    680 
    681 PRStatus
    682 _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 PRStatus
    690 _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 void
    698 _MD_YIELD(void)
    699 {
    700     PR_NOT_REACHED("_MD_YIELD should not be called for Solaris");
    701 }
    702 
    703 PRStatus
    704 _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_SETJMP
    717 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 #else
    726 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  
    113113 */
    114114
    115 #if defined(_PR_GLOBAL_THREADS_ONLY) \
    116         || (defined(_PR_PTHREADS) && !defined(LINUX))
     115#if defined(_PR_PTHREADS) && !defined(LINUX)
    117116#define _PR_NATIVE_THREADS
    118117#endif
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/misc/prenv.c

    r2384 r101810  
    4545#define _PR_LOCK_ENV()
    4646#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);
    5447#else
    5548static PRLock *_pr_envLock = NULL;
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/threads/prcmon.c

    r28971 r101810  
    4747#define _PR_UNLOCK_MCACHE()
    4848#else
    49 #ifdef _PR_LOCAL_THREADS_ONLY
    50 #define _PR_NEW_LOCK_MCACHE()
    51 #define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is)
    52 #define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); }
    53 #else
    5449PRLock *_pr_mcacheLock;
    5550#define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock())
    5651#define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock)
    5752#define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock)
    58 #endif
    5953#endif
    6054
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette