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

📄 init.c

📁 这是leon3处理器的交叉编译链
💻 C
字号:
/* Copyright (C) 1992-2000 the Florida State University   Distributed by the Florida State University under the terms of the   GNU Library General Public License.This file is part of Pthreads.Pthreads is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General PublicLicense as published by the Free Software Foundation (version 2).Pthreads is distributed "AS IS" in the hope that it will beuseful, but WITHOUT ANY WARRANTY; without even the impliedwarranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with Pthreads; see the file COPYING.  If not, writeto the Free Software Foundation, 675 Mass Ave, Cambridge,MA 02139, USA.Report problems and direct all questions to:  pthreads-bugs@ada.cs.fsu.edu  @(#)init.c	3.14 11/8/00*/#include "internals.h"#include "setjmp.h"#include <fsu_pthread/debug.h>#ifndef C_CONTEXT_SWITCH#include <sys/stack.h>#include <sparc/frame.h>#include <asm-leon/leonstack.h>/* * additional parameters passed on stack by fake call */#define PARAM_OFFSET 0+2*sizeof(sigset_t)#endif /* !C_CONTEXT_SWITCH */extern pthread_body();#ifdef STACK_CHECKextern int pthread_page_size;#endifextern pthread_cond_t *new_cond[NNSIG];     /* cond for user handlers         */extern struct context_t *new_scp[NNSIG];    /* info for user handlers         *//* * Stack layout: * high +-----------+ + + *      |           | | | FW_REGS_SZ (fp spill area) *      +-----------+ | + *      |           | | | WINDOWSIZE (prev. window for callee save area) *      +-----------+ | + *      |           | PTHREAD_BODY_OFFSET (space for pthread_body()) *      |           | | *      +-----------+ + start of user stack space *      |           | | *      |           | | *      |           | | *      |           | | *      |           | attr.stacksize (space for user functions) *      |           | | *      |           | | *      |           | | *      |           | | *      +-----------+ + end of user stack space *      | --------- | | + *      |  locked   | | pthread_page_size: locked page, bus error on overflow *      | --------- | | + PA(stack_base): next smallest page aligned address *      |           | 2*pthread_page_size *      |           | | * low  +-----------+ + stack_base * * ifdef STACK_CHECK: * Lock the closest page to the end of the stack to cause a bus error * (or and illegal instruction if no signal handler cannot be pushed * because the stack limit is exceeded, causes bad signal stack message) * on stack overflow. We allocate space conservatively (two pages) to * ensure that the locked page does not cross into the allocated stack * stack due to page alignment. Notice that only whole pages can be * locked, i.e. smaller amounts will be extended to the next page * boundary. *//*------------------------------------------------------------*//* * pthread_initialize - associate stack space with thread */void pthread_initialize(t)pthread_t t;{  struct sparc_stackframe_regs *sp;  unsigned int fpspill = 0;  PTRACEIN;#ifdef STACK_CHECK  sp = (struct sparc_stackframe_regs *) (t->stack_base + #ifdef SIGNAL_STACK     pthread_page_size * 4 +#else /* !SIGNAL_STACK */     pthread_page_size * 2 +#endif /* !SIGNAL_STACK */     SA(t->attr.stacksize + PTHREAD_BODY_OFFSET - WINDOWSIZE));#else /* !STACK_CHECK */  sp = (struct sparc_stackframe_regs *)#ifndef _SOFT_FLOAT    (t->stack_base + SA(t->attr.stacksize + PTHREAD_BODY_OFFSET - ((WINDOWSIZE*2) + FW_REGS_SZ)));  fpspill = ((unsigned int)sp) + (WINDOWSIZE*2);#else      (t->stack_base + SA(t->attr.stacksize + PTHREAD_BODY_OFFSET - ((WINDOWSIZE*2))));#endif    #endif /* !STACK_CHECK */  /*   * set up a jump buffer environment, then manipulate the pc and stack   */  thread_setjmp(t->context, FALSE);  t->pt_reent._errno = errno;  t->context[THREAD_JB_FPUCTX] = fpspill;  t->context[THREAD_JB_SP] = (int) sp;  t->context[THREAD_JB_PC] = (int) pthread_body;  t->context[THREAD_JB_PC] -= RETURN_OFFSET;  sp->sf_ins[6] = ((int) sp) + WINDOWSIZE; /* fp */}#ifndef C_CONTEXT_SWITCH/*------------------------------------------------------------*//* * pthread_push_fake_call - push a user handler for a signal on some thread's  * stack. The user handler will be the first code executed when control * returns to the thread. */void pthread_push_fake_call(p, handler_addr, sig, scp, handler_mask)     pthread_t p;     void (*handler_addr)();     int sig;     struct context_t *scp;     sigset_t *handler_mask;{  extern void pthread_fake_call_wrapper();  struct frame *framep;  int new_context = scp == (struct context_t *) DIRECTED_AT_THREAD;  PTRACEIN;  /*   * create a new frame for the wrapper, and bind sp of the new    * frame to the frame structure.   */  if (new_context) {                /* init context structure if neccessary */                                    /* allocate space on stack */    scp = (struct context_t *)      (p->context[THREAD_JB_SP] - SA(sizeof(struct context_t)));    /*     * need space for new window and 2 params on stack     */    framep = (struct frame *) ((int) scp - SA(MINFRAME + PARAM_OFFSET));    pthread_sigcpyset2set(&scp->sc_mask, &p->mask);    scp->sc_sp = p->context[THREAD_JB_SP];    /*     * The offset will be subtracted in the wrapper to hide this issue     * from the user (in case he changes the return address)     */    scp->sc_pc = p->context[THREAD_JB_PC];#if defined(ASM_SETJMP) || !defined(C_CONTEXT_SWITCH)    scp->sc_pc += RETURN_OFFSET;#endif /* defined(ASM_SETJMP) || !defined(C_CONTEXT_SWITCH) */  }  else    framep = (struct frame *) (p->context[THREAD_JB_SP] - SA(MINFRAME + PARAM_OFFSET));  framep->fr_savfp = (struct frame *) p->context[THREAD_JB_SP];                                    /* put fp in saved area of i6. */  framep->fr_savpc = p->context[THREAD_JB_PC];                                    /* put pc in saved area of i7. */#ifndef ASM_SETJMP  framep->fr_savpc -= RETURN_OFFSET;#endif /* !ASM_SETJMP */  framep->fr_arg[0] = (int) handler_addr;                                    /* save handler's address as i0. */  framep->fr_arg[1] = (int) &framep->fr_argx[0]; /* save ptr->sig mask as i1. */  pthread_sigcpyset2set(&framep->fr_argx[0], &p->mask); /* sig mask on stack. */  framep->fr_arg[2] = sig;          /* arg0 to user handler in i2. */  framep->fr_arg[3] = (int) &p->sig_info[sig == -1 ? 0 : sig];				    /* arg1 to user handler in i3. */  framep->fr_arg[4] = (int) scp;    /* arg2 to user handler in i4. */  framep->fr_arg[5] = new_context;  /* used by wrapper to restore context */  framep->fr_local[6] = (int) (p->cond ? p->cond : (sig == -1 ? NULL : new_cond[sig])); /* addr. of inter. cond. wait in l6 */  if (sig != -1)    new_cond[sig] = NULL;  framep->fr_local[7] = (int) (sig == -1 ? NULL : new_scp[sig]);   /* old context pointer in l7 */  if (sig != -1)    new_scp[sig] = NULL;  p->context[THREAD_JB_SP] = (int) framep;     /* store new sp */  p->context[THREAD_JB_PC] = (int) pthread_fake_call_wrapper; /* store new pc */#if defined(ASM_SETJMP) || !defined(C_CONTEXT_SWITCH)  p->context[THREAD_JB_PC] -= RETURN_OFFSET;#endif /* defined(ASM_SETJMP) || !defined(C_CONTEXT_SWITCH) */  if (handler_mask)    pthread_sigcpyset2set(&p->mask, handler_mask); /* new thread mask */  if (sig > 0)    sigaddset(&p->mask, sig);}#endif /* !C_CONTEXT_SWITCH *//*------------------------------------------------------------*/

⌨️ 快捷键说明

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