⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 solaris.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    ts.tv_nsec = 1000000*n;    if (syscall(SYS_nanosleep, &ts, 0, 0) < 0) {        PR_ASSERT(0);    }}      #define VALID_SP(sp, bottom, top)   \	(((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top)))void solaris_record_regs(PRThread *t, prstatus_t *lwpstatus){#ifdef sparc	long *regs = (long *)&t->md.context.uc_mcontext.gregs[0];	PR_ASSERT(_PR_IS_GCABLE_THREAD(t));	PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[REG_G7]);	t->md.sp = lwpstatus->pr_reg[REG_SP];	PR_ASSERT(VALID_SP(t->md.sp, t->stack->stackBottom, t->stack->stackTop));	regs[0] = lwpstatus->pr_reg[R_G1];	regs[1] = lwpstatus->pr_reg[R_G2];	regs[2] = lwpstatus->pr_reg[R_G3];	regs[3] = lwpstatus->pr_reg[R_G4];	regs[4] = lwpstatus->pr_reg[R_O0];	regs[5] = lwpstatus->pr_reg[R_O1];	regs[6] = lwpstatus->pr_reg[R_O2];	regs[7] = lwpstatus->pr_reg[R_O3];	regs[8] = lwpstatus->pr_reg[R_O4];	regs[9] = lwpstatus->pr_reg[R_O5];	regs[10] = lwpstatus->pr_reg[R_O6];	regs[11] = lwpstatus->pr_reg[R_O7];#elif defined(i386)	/*	 * To be implemented and tested	 */	PR_ASSERT(0);	PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[GS]);	t->md.sp = lwpstatus->pr_reg[UESP];#endif}   void solaris_preempt_off(){    sigset_t set;     (void)sigfillset(&set);    syscall(SYS_sigprocmask, SIG_SETMASK, &set, &old_mask);}void solaris_preempt_on(){    syscall(SYS_sigprocmask, SIG_SETMASK, &old_mask, NULL);      }int solaris_open_main_proc_fd(){    char buf[30];    int fd;    /* Not locked, so must be created while threads coming up */    PR_snprintf(buf, sizeof(buf), "/proc/%ld", getpid());    if ( (fd = syscall(SYS_open, buf, O_RDONLY)) < 0) {        return -1;    }    return fd;}/* Return a file descriptor for the /proc entry corresponding to the * given lwp.  */int solaris_open_lwp(lwpid_t id, int lwp_main_proc_fd){    int result;    if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCOPENLWP, &id)) <0)        return -1; /* exited??? */    return result;}void _MD_Begin_SuspendAll(){    solaris_preempt_off();    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n"));    /* run at highest prio so I cannot be preempted */    thr_getprio(thr_self(), &gcprio);    thr_setprio(thr_self(), 0x7fffffff);     suspendAllOn = PR_TRUE;    suspendAllThread = _PR_MD_CURRENT_THREAD();}void _MD_End_SuspendAll(){}void _MD_End_ResumeAll(){    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n"));    thr_setprio(thr_self(), gcprio);    solaris_preempt_on();    suspendAllThread = NULL;    suspendAllOn = PR_FALSE;}void _MD_Suspend(PRThread *thr){   int lwp_fd, result;   prstatus_t lwpstatus;   int lwp_main_proc_fd = 0;     if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){     /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend      * during that time we can't call any thread lib or libc calls. Hence      * make sure that no suspension is requested for Non gcable thread      * during suspendAllOn */      PR_ASSERT(!suspendAllOn);      thr_suspend(thr->md.handle);      return;   }    /* XXX Primordial thread can't be bound to an lwp, hence there is no     * way we can assume that we can get the lwp status for primordial     * thread reliably. Hence we skip this for primordial thread, hoping     * that the SP is saved during lock and cond. wait.      * XXX - Again this is concern only for java interpreter, not for the     * server, 'cause primordial thread in the server does not do java work     */    if (thr->flags & _PR_PRIMORDIAL)      return;        /* XXX Important Note: If the start function of a thread is not called,     * lwpid is -1. Then, skip this thread. This thread will get caught     * in PR_NativeRunThread before calling the start function, because     * we hold the pr_activeLock during suspend/resume */    /* if the thread is not started yet then don't do anything */    if (!suspendAllOn || thr->md.lwpid == -1)      return;    if (_lwp_suspend(thr->md.lwpid) < 0) {        PR_ASSERT(0);       return;    }    if ( (lwp_main_proc_fd = solaris_open_main_proc_fd()) < 0) {        PR_ASSERT(0);        return;   /* XXXMB ARGH, we're hosed! */    }   if ( (lwp_fd = solaris_open_lwp(thr->md.lwpid, lwp_main_proc_fd)) < 0) {           PR_ASSERT(0);           close(lwp_main_proc_fd);	   return;   }   if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {            /* Hopefully the thread just died... */           close(lwp_fd);           close(lwp_main_proc_fd);	   return;   }            while ( !(lwpstatus.pr_flags & PR_STOPPED) ) {                if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {                    PR_ASSERT(0);  /* ARGH SOMETHING WRONG! */                    break;                }                solaris_msec_sleep(1);            }            solaris_record_regs(thr, &lwpstatus);            close(lwp_fd);   close(lwp_main_proc_fd);}#ifdef OLD_CODEvoid _MD_SuspendAll(){    /* On solaris there are threads, and there are LWPs.      * Calling _PR_DoSingleThread would freeze all of the threads bound to LWPs     * but not necessarily stop all LWPs (for example if someone did     * an attachthread of a thread which was not bound to an LWP).     * So now go through all the LWPs for this process and freeze them.     *     * Note that if any thread which is capable of having the GC run on it must     * had better be a LWP with a single bound thread on it.  Otherwise, this      * might not stop that thread from being run.     */    PRThread *current = _PR_MD_CURRENT_THREAD();    prstatus_t status, lwpstatus;    int result, index, lwp_fd;    lwpid_t me = _lwp_self();    int err;    int lwp_main_proc_fd;    solaris_preempt_off();    /* run at highest prio so I cannot be preempted */    thr_getprio(thr_self(), &gcprio);    thr_setprio(thr_self(), 0x7fffffff);     current->md.sp = (uint_t)&me;	/* set my own stack pointer */    if ( (lwp_main_proc_fd = solaris_open_main_proc_fd()) < 0) {        PR_ASSERT(0);        solaris_preempt_on();        return;   /* XXXMB ARGH, we're hosed! */    }    if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCSTATUS, &status)) < 0) {        err = errno;        PR_ASSERT(0);        goto failure;   /* XXXMB ARGH, we're hosed! */    }    num_lwps = status.pr_nlwp;    if ( (all_lwps = (lwpid_t *)PR_MALLOC((num_lwps+1) * sizeof(lwpid_t)))==NULL) {        PR_ASSERT(0);        goto failure;   /* XXXMB ARGH, we're hosed! */    }               if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCLWPIDS, all_lwps)) < 0) {        PR_ASSERT(0);        PR_DELETE(all_lwps);        goto failure;   /* XXXMB ARGH, we're hosed! */    }    for (index=0; index< num_lwps; index++) {        if (all_lwps[index] != me)  {            if (_lwp_suspend(all_lwps[index]) < 0) {                 /* could happen if lwp exited */                all_lwps[index] = me;	/* dummy it up */            }        }    }    /* Turns out that lwp_suspend is not a blocking call.     * Go through the list and make sure they are all stopped.     */    for (index=0; index< num_lwps; index++) {        if (all_lwps[index] != me)  {            if ( (lwp_fd = solaris_open_lwp(all_lwps[index], lwp_main_proc_fd)) < 0) {                PR_ASSERT(0);                PR_DELETE(all_lwps);                all_lwps = NULL;                goto failure;   /* XXXMB ARGH, we're hosed! */            }            if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {                /* Hopefully the thread just died... */                close(lwp_fd);                continue;            }            while ( !(lwpstatus.pr_flags & PR_STOPPED) ) {                if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {                    PR_ASSERT(0);  /* ARGH SOMETHING WRONG! */                    break;                }                solaris_msec_sleep(1);            }            solaris_record_regs(&lwpstatus);            close(lwp_fd);        }    }    close(lwp_main_proc_fd);    return;failure:    solaris_preempt_on();    thr_setprio(thr_self(), gcprio);    close(lwp_main_proc_fd);    return;}void _MD_ResumeAll(){    int i;    lwpid_t me = _lwp_self();     for (i=0; i < num_lwps; i++) {        if (all_lwps[i] == me)            continue;        if ( _lwp_continue(all_lwps[i]) < 0) {            PR_ASSERT(0);  /* ARGH, we are hosed! */        }    }    /* restore priority and sigmask */    thr_setprio(thr_self(), gcprio);    solaris_preempt_on();    PR_DELETE(all_lwps);    all_lwps = NULL;}#endif /* OLD_CODE */#ifdef USE_SETJMPPRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np){    if (isCurrent) {		(void) setjmp(CONTEXT(t));    }    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);    return (PRWord *) CONTEXT(t);}#elsePRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np){    if (isCurrent) {		(void) getcontext(CONTEXT(t));    }    *np = NGREG;    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];}#endif  /* USE_SETJMP */#else /* _PR_GLOBAL_THREADS_ONLY */#if defined(_PR_LOCAL_THREADS_ONLY)void _MD_EarlyInit(void){}void _MD_SolarisInit(){    _PR_UnixInit();}void_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri){    return;}PRStatus_MD_InitializeThread(PRThread *thread){	return PR_SUCCESS;}PRStatus_MD_WAIT(PRThread *thread, PRIntervalTime ticks){    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));    _PR_MD_SWITCH_CONTEXT(thread);    return PR_SUCCESS;}PRStatus_MD_WAKEUP_WAITER(PRThread *thread){	PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE)));    return PR_SUCCESS;}/* These functions should not be called for Solaris */void_MD_YIELD(void){    PR_NOT_REACHED("_MD_YIELD should not be called for Solaris");}PRStatus_MD_CREATE_THREAD(    PRThread *thread,    void (*start) (void *),    PRThreadPriority priority,    PRThreadScope scope,    PRThreadState state,    PRUint32 stackSize){    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris");	return(PR_FAILURE);}#ifdef USE_SETJMPPRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np){    if (isCurrent) {		(void) setjmp(CONTEXT(t));    }    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);    return (PRWord *) CONTEXT(t);}#elsePRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np){    if (isCurrent) {		(void) getcontext(CONTEXT(t));    }    *np = NGREG;    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];}#endif  /* USE_SETJMP */#endif  /* _PR_LOCAL_THREADS_ONLY */#endif /* _PR_GLOBAL_THREADS_ONLY */#ifndef _PR_PTHREADS#if defined(i386) && defined(SOLARIS2_4)/*  * Because clock_gettime() on Solaris/x86 2.4 always generates a * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(), * which is implemented using gettimeofday(). */int_pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp){    struct timeval tv;    if (clock_id != CLOCK_REALTIME) {	errno = EINVAL;	return -1;    }    gettimeofday(&tv, NULL);    tp->tv_sec = tv.tv_sec;    tp->tv_nsec = tv.tv_usec * 1000;    return 0;}#endif  /* i386 && SOLARIS2_4 */#endif  /* _PR_PTHREADS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -