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

📄 irix.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    	_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];#ifndef _PR_USE_POLL    	FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));#endif	}}void_MD_ExitThread(PRThread *thread){    if (thread->flags & _PR_GLOBAL_SCOPE) {        _MD_ATOMIC_DECREMENT(&_pr_md_irix_sprocs);        _MD_CLEAN_THREAD(thread);        _MD_SET_CURRENT_THREAD(NULL);    }}void_MD_SuspendCPU(_PRCPU *cpu){    PRInt32 rv;	cpu->md.suspending_id = getpid();	rv = kill(cpu->md.id, SIGUSR1);	PR_ASSERT(rv == 0);	/*	 * now, block the current thread/cpu until woken up by the suspended	 * thread from it's SIGUSR1 signal handler	 */	blockproc(getpid());}void_MD_ResumeCPU(_PRCPU *cpu){    unblockproc(cpu->md.id);}#if 0/* * save the register context of a suspended sproc */void get_context(PRThread *thr){    int len, fd;    char pidstr[24];    char path[24];    /*     * open the file corresponding to this process in procfs     */    sprintf(path,"/proc/%s","00000");    len = strlen(path);    sprintf(pidstr,"%d",thr->md.id);    len -= strlen(pidstr);    sprintf(path + len,"%s",pidstr);    fd = open(path,O_RDONLY);    if (fd >= 0) {        (void) ioctl(fd, PIOCGREG, thr->md.gregs);        close(fd);    }    return;}#endif	/* 0 */void_MD_SuspendThread(PRThread *thread){    PRInt32 rv;    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&        _PR_IS_GCABLE_THREAD(thread));	thread->md.suspending_id = getpid();	rv = kill(thread->md.id, SIGUSR1);	PR_ASSERT(rv == 0);	/*	 * now, block the current thread/cpu until woken up by the suspended	 * thread from it's SIGUSR1 signal handler	 */	blockproc(getpid());}void_MD_ResumeThread(PRThread *thread){    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&        _PR_IS_GCABLE_THREAD(thread));    (void)unblockproc(thread->md.id);}/* * return the set of processors available for scheduling procs in the * "mask" argument */PRInt32 _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask){    PRInt32 nprocs, rv;    struct pda_stat *pstat;#define MAX_PROCESSORS    32    nprocs = sysmp(MP_NPROCS);    if (nprocs < 0)        return(-1);    pstat = (struct pda_stat*)PR_MALLOC(sizeof(struct pda_stat) * nprocs);    if (pstat == NULL)        return(-1);    rv = sysmp(MP_STAT, pstat);    if (rv < 0) {        PR_DELETE(pstat);        return(-1);    }    /*     * look at the first 32 cpus     */    nprocs = (nprocs > MAX_PROCESSORS) ? MAX_PROCESSORS : nprocs;    *mask = 0;    while (nprocs) {        if ((pstat->p_flags & PDAF_ENABLED) &&            !(pstat->p_flags & PDAF_ISOLATED)) {            *mask |= (1 << pstat->p_cpuid);        }        nprocs--;        pstat++;    }    return 0;}static char *_thr_state[] = {    "UNBORN",    "RUNNABLE",    "RUNNING",    "LOCK_WAIT",    "COND_WAIT",    "JOIN_WAIT",    "IO_WAIT",    "SUSPENDED",    "DEAD"};void _PR_List_Threads(){    PRThread *thr;    void *handle;    struct _PRCPU *cpu;    PRCList *qp;    int len, fd;    char pidstr[24];    char path[24];    prpsinfo_t pinfo;    printf("\n%s %-s\n"," ","LOCAL Threads");    printf("%s %-s\n"," ","----- -------");    printf("%s %-14s %-10s %-12s %-3s %-10s %-10s %-12s\n\n"," ",        "Thread", "State", "Wait-Handle",        "Cpu","Stk-Base","Stk-Sz","SP");    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {        thr = _PR_ACTIVE_THREAD_PTR(qp);        printf("%s 0x%-12x %-10s "," ",thr,_thr_state[thr->state]);        if (thr->state == _PR_LOCK_WAIT)            handle = thr->wait.lock;        else if (thr->state == _PR_COND_WAIT)            handle = thr->wait.cvar;        else            handle = NULL;        if (handle)            printf("0x%-10x ",handle);        else            printf("%-12s "," ");        printf("%-3d ",thr->cpu->id);        printf("0x%-8x ",thr->stack->stackBottom);        printf("0x%-8x ",thr->stack->stackSize);        printf("0x%-10x\n",thr->md.jb[JB_SP]);    }    printf("\n%s %-s\n"," ","GLOBAL Threads");    printf("%s %-s\n"," ","------ -------");    printf("%s %-14s %-6s %-12s %-12s %-12s %-12s\n\n"," ","Thread",        "Pid","State","Wait-Handle",        "Stk-Base","Stk-Sz");    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {        thr = _PR_ACTIVE_THREAD_PTR(qp);        if (thr->cpu != NULL)            continue;        /* it is a cpu thread */        printf("%s 0x%-12x %-6d "," ",thr,thr->md.id);        /*         * check if the sproc is still running         * first call prctl(PR_GETSHMASK,pid) to check if         * the process is part of the share group (the pid         * could have been recycled by the OS)         */        if (prctl(PR_GETSHMASK,thr->md.id) < 0) {            printf("%-12s\n","TERMINATED");            continue;        }        /*         * Now, check if the sproc terminated and is in zombie         * state         */        sprintf(path,"/proc/pinfo/%s","00000");        len = strlen(path);        sprintf(pidstr,"%d",thr->md.id);        len -= strlen(pidstr);        sprintf(path + len,"%s",pidstr);        fd = open(path,O_RDONLY);        if (fd >= 0) {            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)                printf("%-12s ","TERMINATED");            else if (pinfo.pr_zomb)                printf("%-12s ","TERMINATED");            else                printf("%-12s ",_thr_state[thr->state]);            close(fd);        } else {            printf("%-12s ","TERMINATED");        }        if (thr->state == _PR_LOCK_WAIT)            handle = thr->wait.lock;        else if (thr->state == _PR_COND_WAIT)            handle = thr->wait.cvar;        else            handle = NULL;        if (handle)            printf("%-12x ",handle);        else            printf("%-12s "," ");        printf("0x%-10x ",thr->stack->stackBottom);        printf("0x%-10x\n",thr->stack->stackSize);    }    printf("\n%s %-s\n"," ","CPUs");    printf("%s %-s\n"," ","----");    printf("%s %-14s %-6s %-12s \n\n"," ","Id","Pid","State");    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {        cpu = _PR_CPU_PTR(qp);        printf("%s %-14d %-6d "," ",cpu->id,cpu->md.id);        /*         * check if the sproc is still running         * first call prctl(PR_GETSHMASK,pid) to check if         * the process is part of the share group (the pid         * could have been recycled by the OS)         */        if (prctl(PR_GETSHMASK,cpu->md.id) < 0) {            printf("%-12s\n","TERMINATED");            continue;        }        /*         * Now, check if the sproc terminated and is in zombie         * state         */        sprintf(path,"/proc/pinfo/%s","00000");        len = strlen(path);        sprintf(pidstr,"%d",cpu->md.id);        len -= strlen(pidstr);        sprintf(path + len,"%s",pidstr);        fd = open(path,O_RDONLY);        if (fd >= 0) {            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)                printf("%-12s\n","TERMINATED");            else if (pinfo.pr_zomb)                printf("%-12s\n","TERMINATED");            else                printf("%-12s\n","RUNNING");            close(fd);        } else {            printf("%-12s\n","TERMINATED");        }    }    fflush(stdout);}#endif /* defined(_PR_PTHREADS) */ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np){#if !defined(_PR_PTHREADS)    if (isCurrent) {        (void) setjmp(t->md.jb);    }    *np = sizeof(t->md.jb) / sizeof(PRWord);    return (PRWord *) (t->md.jb);#else	*np = 0;	return NULL;#endif}void _MD_EarlyInit(void){#if !defined(_PR_PTHREADS)    char *eval;    int fd;	extern int __ateachexit(void (*func)(void));    sigemptyset(&ints_off);    sigaddset(&ints_off, SIGALRM);    sigaddset(&ints_off, SIGIO);    sigaddset(&ints_off, SIGCLD);    if (eval = getenv("_NSPR_TERMINATE_ON_ERROR"))        _nspr_terminate_on_error = (0 == atoi(eval) == 0) ? PR_FALSE : PR_TRUE;    fd = open("/dev/zero",O_RDWR , 0);    if (fd < 0) {        perror("open /dev/zero failed");        exit(1);    }    /*     * Set up the sproc private data area.     * This region exists at the same address, _nspr_sproc_private, for     * every sproc, but each sproc gets a private copy of the region.     */    _nspr_sproc_private = (char*)mmap(0, _pr_pageSize, PROT_READ | PROT_WRITE,        MAP_PRIVATE| MAP_LOCAL, fd, 0);    if (_nspr_sproc_private == (void*)-1) {        perror("mmap /dev/zero failed");        exit(1);    }	_MD_SET_SPROC_PID(getpid());	    close(fd);	__ateachexit(irix_detach_sproc);#endif    _MD_IrixIntervalInit();}  /* _MD_EarlyInit */void _MD_IrixInit(void){#if !defined(_PR_PTHREADS)    struct sigaction sigact;    PRThread *me = _PR_MD_CURRENT_THREAD();	int rv;#ifdef _PR_HAVE_SGI_PRDA_PROCMASK	/*	 * enable user-level processing of sigprocmask(); this is an undocumented	 * feature available in Irix 6.2, 6.3, 6.4 and 6.5	 */	__sgi_prda_procmask(USER_LEVEL);#endif	/*	 * set up SIGUSR1 handler; this is used to save state	 * during PR_SuspendAll	 */	sigact.sa_handler = save_context_and_block;	sigact.sa_flags = SA_RESTART;	sigact.sa_mask = ints_off;	sigaction(SIGUSR1, &sigact, 0);    /*     * Change the name of the core file from core to core.pid,     * This is inherited by the sprocs created by this process     */#ifdef PR_COREPID    prctl(PR_COREPID, 0, 1);#endif    /*     * Irix-specific terminate on error processing     */	/*	 * PR_SETABORTSIG is a new command implemented in a patch to	 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all	 * sprocs in the process when one of them terminates abnormally	 *	 */	if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {		/*		 *  if (errno == EINVAL)		 *		 *	PR_SETABORTSIG not supported under this OS.		 *	You may want to get a recent kernel rollup patch that		 *	supports this feature.		 *		 */	}	/*	 * PR_SETEXITSIG -  send the SIGCLD signal to the parent	 *            sproc when any sproc terminates	 *	 *    This is used to cause the entire application to	 *    terminate when    any sproc terminates abnormally by	 *     receipt of a SIGSEGV, SIGBUS or SIGABRT signal.	 *    If this is not done, the application may seem	 *     "hung" to the user because the other sprocs may be	 *    waiting for resources held by the	 *    abnormally-terminating sproc.	 */	prctl(PR_SETEXITSIG, 0);	sigact.sa_handler = sigchld_handler;	sigact.sa_flags = SA_RESTART;	sigact.sa_mask = ints_off;	sigaction(SIGCLD, &sigact, NULL);    /*     * setup stack fields for the primordial thread     */    me->stack->stackSize = prctl(PR_GETSTACKSIZE);    me->stack->stackBottom = me->stack->stackTop - me->stack->stackSize;    rv = pipe(_pr_irix_primoridal_cpu_fd);    PR_ASSERT(rv == 0);#ifndef _PR_USE_POLL    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];    FD_SET(_pr_irix_primoridal_cpu_fd[0], &_PR_FD_READ_SET(me->cpu));#endif	libc_handle = dlopen("libc.so",RTLD_NOW);	PR_ASSERT(libc_handle != NULL);	libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");	PR_ASSERT(libc_exit != NULL);	/* dlclose(libc_handle); */#endif /* _PR_PTHREADS */    _PR_UnixInit();}/**************************************************************************//************** code and such for NSPR 2.0's interval times ***************//**************************************************************************/#define PR_PSEC_PER_SEC 1000000000000ULL  /* 10^12 */#ifndef SGI_CYCLECNTR_SIZE#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */#endifstatic PRIntn mmem_fd = -1;static PRIntn clock_width = 0;static void *iotimer_addr = NULL;static PRUint32 pr_clock_mask = 0;static PRUint32 pr_clock_shift = 0;static PRIntervalTime pr_ticks = 0;static PRUint32 pr_clock_granularity = 1;static PRUint32 pr_previous = 0, pr_residual = 0;static PRUint32 pr_ticks_per_second = 0;extern PRIntervalTime _PR_UNIX_GetInterval(void);extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);static void _MD_IrixIntervalInit(void){    /*     * As much as I would like, the service available through this     * interface on R3000's (aka, IP12) just isn't going to make it.     * The register is only 24 bits wide, and rolls over at a verocious     * rate.     */    PRUint32 one_tick = 0;    struct utsname utsinfo;    uname(&utsinfo);    if ((strncmp("IP12", utsinfo.machine, 4) != 0)        && ((mmem_fd = open("/dev/mmem", O_RDONLY)) != -1))    {        int poffmask = getpagesize() - 1;        __psunsigned_t phys_addr, raddr, cycleval;        phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);        raddr = phys_addr & ~poffmask;        iotimer_addr = mmap(            0, poffmask, PROT_READ, MAP_PRIVATE, mmem_fd, (__psint_t)raddr);        clock_width = syssgi(SGI_CYCLECNTR_SIZE);        if (clock_width < 0)        {            /*              * We must be executing on a 6.0 or earlier system, since the             * SGI_CYCLECNTR_SIZE call is not supported.             *              * The only pre-6.1 platforms with 64-bit counters are             * IP19 and IP21 (Challenge, PowerChallenge, Onyx).             */            if (!strncmp(utsinfo.machine, "IP19", 4) ||                !strncmp(utsinfo.machine, "IP21", 4))                clock_width = 64;            else                clock_width = 32;        }        /*         * 'cycleval' is picoseconds / increment of the counter.         * I'm pushing for a tick to be 100 microseconds, 10^(-4).         * That leaves 10^(-8) left over, or 10^8 / cycleval.         * Did I do that right?         */        one_tick =  100000000UL / cycleval ;  /* 100 microseconds */        while (0 != one_tick)        {            pr_clock_shift += 1;            one_tick = one_tick >> 1;            pr_clock_granularity = pr_clock_granularity << 1;        }        pr_clock_mask = pr_clock_granularity - 1;  /* to make a mask out of it */        pr_ticks_per_second = PR_PSEC_PER_SEC                / ((PRUint64)pr_clock_granularity * (PRUint64)cycleval);                    iotimer_addr = (void*)            ((__psunsigned_t)iotimer_addr + (phys_addr & poffmask));    }    else    {        pr_ticks_per_second = _PR_UNIX_TicksPerSecond();    }}  /* _MD_IrixIntervalInit */PRIntervalTime _MD_IrixIntervalPerSec(void){    return pr_ticks_per_second;}PRIntervalTime _MD_IrixGetInterval(void){    if (mmem_fd != -1)    {        if (64 == clock_width)        {            PRUint64 temp = *(PRUint64*)iotimer_addr;            pr_ticks = (PRIntervalTime)(temp >> pr_clock_shift);        }        else        {            PRIntervalTime ticks = pr_ticks;            PRUint32 now = *(PRUint32*)iotimer_addr, temp;            PRUint32 residual = pr_residual, previous = pr_previous;            temp = now - previous + residual;            residual = temp & pr_clock_mask;            ticks += temp >> pr_clock_shift;            pr_previous = now;            pr_residual = residual;            pr_ticks = ticks;        }    }    else    {        /*         * No fast access. Use the time of day clock. This isn't the         * right answer since this clock can get set back, tick at odd         * rates, and it's expensive to acqurie.         */        pr_ticks = _PR_UNIX_GetInterval();    }    return pr_ticks;}  /* _MD_IrixGetInterval */

⌨️ 快捷键说明

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