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

📄 cpu.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
 */void _CPU_Context_restore(  Context_Control  *next){  Context_Control_overlay *nextp = (Context_Control_overlay *)next;  _CPU_ISR_Enable(nextp->isr_level);  longjmp( nextp->regs, 0 );}/*PAGE * *  _CPU_Context_switch */static void do_jump(  Context_Control_overlay *currentp,  Context_Control_overlay *nextp);void _CPU_Context_switch(  Context_Control  *current,  Context_Control  *next){  Context_Control_overlay *currentp = (Context_Control_overlay *)current;  Context_Control_overlay *nextp = (Context_Control_overlay *)next;#if 0  int status;#endif  currentp->isr_level = _CPU_ISR_Disable_support();  do_jump( currentp, nextp );#if 0  if (sigsetjmp(currentp->regs, 1) == 0) {    /* Save the current context */     siglongjmp(nextp->regs, 0);           /* Switch to the new context */     _Internal_error_Occurred(         INTERNAL_ERROR_CORE,         TRUE,         status       );  }#endif#ifdef RTEMS_DEBUG    if (_CPU_ISR_Get_level() == 0)       abort();#endif  _CPU_ISR_Enable(currentp->isr_level);}static void do_jump(  Context_Control_overlay *currentp,  Context_Control_overlay *nextp){  int status;  if (setjmp(currentp->regs) == 0) {    /* Save the current context */     longjmp(nextp->regs, 0);           /* Switch to the new context */     _Internal_error_Occurred(         INTERNAL_ERROR_CORE,         TRUE,         status       );  }}/*PAGE * *  _CPU_Save_float_context */void _CPU_Save_float_context(  Context_Control_fp *fp_context){}/*PAGE * *  _CPU_Restore_float_context */void _CPU_Restore_float_context(  Context_Control_fp *fp_context){}/*PAGE * *  _CPU_ISR_Disable_support */unsigned32 _CPU_ISR_Disable_support(void){  int status;  sigset_t  old_mask;  sigemptyset( &old_mask );  status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);  if ( status )    _Internal_error_Occurred(      INTERNAL_ERROR_CORE,      TRUE,      status    );  if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))    return 1;  return 0;}/*PAGE * *  _CPU_ISR_Enable */void _CPU_ISR_Enable(  unsigned32 level){  int status;  if (level == 0)    status = sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);  else    status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);  if ( status )    _Internal_error_Occurred(      INTERNAL_ERROR_CORE,      TRUE,      status    );}/*PAGE * *  _CPU_ISR_Handler * *  External interrupt handler. *  This is installed as a UNIX signal handler. *  It vectors out to specific user interrupt handlers. */void _CPU_ISR_Handler(int vector){  extern void        _Thread_Dispatch(void);  extern unsigned32  _Thread_Dispatch_disable_level;  extern boolean     _Context_Switch_necessary;  if (_ISR_Nest_level++ == 0) {      /* switch to interrupt stack */  }  _Thread_Dispatch_disable_level++;  if (_ISR_Vector_table[vector]) {     _ISR_Vector_table[vector](vector);  } else {     _CPU_Stray_signal(vector);  }  if (_ISR_Nest_level-- == 0) {      /* switch back to original stack */  }  _Thread_Dispatch_disable_level--;  if (_Thread_Dispatch_disable_level == 0 &&      (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) {      _ISR_Signals_to_thread_executing = FALSE;      _CPU_ISR_Enable(0);      _Thread_Dispatch();  }}/*PAGE * *  _CPU_Stray_signal */void _CPU_Stray_signal(int sig_num){  char buffer[ 4 ];  /*   * print "stray" msg about ones which that might mean something   * Avoid using the stdio section of the library.   * The following is generally safe.   */  switch (sig_num)  {#ifdef SIGCLD      case SIGCLD:          break;#endif      default:      {        /*         *  We avoid using the stdio section of the library.         *  The following is generally safe         */        int digit;        int number = sig_num;        int len = 0;        digit = number / 100;        number %= 100;        if (digit) buffer[len++] = '0' + digit;        digit = number / 10;        number %= 10;        if (digit || len) buffer[len++] = '0' + digit;        digit = number;        buffer[len++] = '0' + digit;        buffer[ len++ ] = '\n';        write( 2, "Stray signal ", 13 );        write( 2, buffer, len );      }  }  /*   * If it was a "fatal" signal, then exit here   * If app code has installed a hander for one of these, then   * we won't call _CPU_Stray_signal, so this is ok.   */  switch (sig_num) {      case SIGINT:      case SIGHUP:      case SIGQUIT:      case SIGILL:#ifdef SIGEMT      case SIGEMT:#endif      case SIGKILL:      case SIGBUS:      case SIGSEGV:      case SIGTERM:#if !defined(__CYGWIN__)      case SIGIOT:#endif        _CPU_Fatal_error(0x100 + sig_num);  }}/*PAGE * *  _CPU_Fatal_error */void _CPU_Fatal_error(unsigned32 error){  setitimer(ITIMER_REAL, 0, 0);  if ( error ) {#ifdef RTEMS_DEBUG    abort();#endif    if (getenv("RTEMS_DEBUG"))      abort();  }  _exit(error);}/* *  Special Purpose Routines to hide the use of UNIX system calls. */int _CPU_Set_sync_io_handler(  int fd,  boolean read,  boolean write,  boolean except,  rtems_sync_io_handler handler){  if ((fd < FD_SETSIZE) && (_CPU_Sync_io_handlers[fd] == NULL)) {    if (read)      FD_SET(fd, &sync_io_readfds);    else      FD_CLR(fd, &sync_io_readfds);    if (write)      FD_SET(fd, &sync_io_writefds);    else      FD_CLR(fd, &sync_io_writefds);    if (except)      FD_SET(fd, &sync_io_exceptfds);    else      FD_CLR(fd, &sync_io_exceptfds);    _CPU_Sync_io_handlers[fd] = handler;    if ((fd + 1) > sync_io_nfds)      sync_io_nfds = fd + 1;    return 0;  }  return -1;}int _CPU_Clear_sync_io_handler(  int fd){  if ((fd < FD_SETSIZE) && _CPU_Sync_io_handlers[fd]) {    FD_CLR(fd, &sync_io_readfds);    FD_CLR(fd, &sync_io_writefds);    FD_CLR(fd, &sync_io_exceptfds);    _CPU_Sync_io_handlers[fd] = NULL;    sync_io_nfds = 0;    for (fd = 0; fd < FD_SETSIZE; fd++)      if (FD_ISSET(fd, &sync_io_readfds) ||          FD_ISSET(fd, &sync_io_writefds) ||          FD_ISSET(fd, &sync_io_exceptfds))        sync_io_nfds = fd + 1;    return 0;  }  return -1;}int _CPU_Get_clock_vector( void ){  return SIGALRM;}void _CPU_Start_clock(  int microseconds){  struct itimerval  new;  new.it_value.tv_sec = 0;  new.it_value.tv_usec = microseconds;  new.it_interval.tv_sec = 0;  new.it_interval.tv_usec = microseconds;  setitimer(ITIMER_REAL, &new, 0);}void _CPU_Stop_clock( void ){  struct itimerval  new;  struct sigaction  act;  /*   * Set the SIGALRM signal to ignore any last   * signals that might come in while we are   * disarming the timer and removing the interrupt   * vector.   */  (void) memset(&act, 0, sizeof(act));  act.sa_handler = SIG_IGN;  sigaction(SIGALRM, &act, 0);  (void) memset(&new, 0, sizeof(new));  setitimer(ITIMER_REAL, &new, 0);}#if 0extern void fix_syscall_errno( void );#endif#define fix_syscall_errno() #if defined(RTEMS_MULTIPROCESSING)int  _CPU_SHM_Semid;void _CPU_SHM_Init(  unsigned32   maximum_nodes,  boolean      is_master_node,  void       **shm_address,  unsigned32  *shm_length){  int          i;  int          shmid;  char        *shm_addr;  key_t        shm_key;  key_t        sem_key;  int          status = 0;  /* to avoid unitialized warnings */  int          shm_size;  if (getenv("RTEMS_SHM_KEY"))    shm_key = strtol(getenv("RTEMS_SHM_KEY"), 0, 0);  else#ifdef RTEMS_SHM_KEY    shm_key = RTEMS_SHM_KEY;#else    shm_key = 0xa000;#endif    if (getenv("RTEMS_SHM_SIZE"))      shm_size = strtol(getenv("RTEMS_SHM_SIZE"), 0, 0);    else#ifdef RTEMS_SHM_SIZE      shm_size = RTEMS_SHM_SIZE;#else      shm_size = 64 * 1024;#endif    if (getenv("RTEMS_SHM_SEMAPHORE_KEY"))      sem_key = strtol(getenv("RTEMS_SHM_SEMAPHORE_KEY"), 0, 0);    else#ifdef RTEMS_SHM_SEMAPHORE_KEY      sem_key = RTEMS_SHM_SEMAPHORE_KEY;#else      sem_key = 0xa001;#endif    shmid = shmget(shm_key, shm_size, IPC_CREAT | 0660);    if ( shmid == -1 ) {      fix_syscall_errno(); /* in case of newlib */      perror( "shmget" );      _CPU_Fatal_halt( 0xdead0001 );    }    shm_addr = shmat(shmid, (char *)0, SHM_RND);    if ( shm_addr == (void *)-1 ) {      fix_syscall_errno(); /* in case of newlib */      perror( "shmat" );      _CPU_Fatal_halt( 0xdead0002 );    }    _CPU_SHM_Semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);    if ( _CPU_SHM_Semid == -1 ) {      fix_syscall_errno(); /* in case of newlib */      perror( "semget" );      _CPU_Fatal_halt( 0xdead0003 );    }    if ( is_master_node ) {      for ( i=0 ; i <= maximum_nodes ; i++ ) {#if !HAS_UNION_SEMUN        union semun {          int val;          struct semid_ds *buf;          unsigned short int *array;#if defined(__linux__)          struct seminfo *__buf;#endif                  } ;#endif        union semun help ;        help.val = 1;        status = semctl( _CPU_SHM_Semid, i, SETVAL, help );        fix_syscall_errno(); /* in case of newlib */        if ( status == -1 ) {          _CPU_Fatal_halt( 0xdead0004 );        }      }    }  *shm_address = shm_addr;  *shm_length = shm_size;}#endifint _CPU_Get_pid( void ){  return getpid();}#if defined(RTEMS_MULTIPROCESSING)/* * Define this to use signals for MPCI shared memory driver. * If undefined, the shared memory driver will poll from the * clock interrupt. * Ref: ../shmsupp/getcfg.c * * BEWARE:: many UN*X kernels and debuggers become severely confused when *          debugging programs which use signals.  The problem is *much* *          worse when using multiple signals, since ptrace(2) tends to *          drop all signals except 1 in the case of multiples. *          On hpux9, this problem was so bad, we couldn't use interrupts *          with the shared memory driver if we ever hoped to debug *          RTEMS programs. *          Maybe systems that use /proc don't have this problem... */int _CPU_SHM_Get_vector( void ){#ifdef CPU_USE_SHM_INTERRUPTS  return SIGUSR1;#else  return 0;#endif}void _CPU_SHM_Send_interrupt(  int pid,  int vector){  kill((pid_t) pid, vector);}void _CPU_SHM_Lock(  int semaphore){  struct sembuf sb;  sb.sem_num = semaphore;  sb.sem_op  = -1;  sb.sem_flg = 0;  while (1) {    int status = -1;    status = semop(_CPU_SHM_Semid, &sb, 1);    if ( status >= 0 )      break;    if ( status == -1 ) {       fix_syscall_errno();    /* in case of newlib */        if (errno == EINTR)            continue;        perror("shm lock");        _CPU_Fatal_halt( 0xdead0005 );    }  }}void _CPU_SHM_Unlock(  int semaphore){  struct sembuf  sb;  int            status;  sb.sem_num = semaphore;  sb.sem_op  = 1;  sb.sem_flg = 0;  while (1) {    status = semop(_CPU_SHM_Semid, &sb, 1);    if ( status >= 0 )      break;    if ( status == -1 ) {      fix_syscall_errno();    /* in case of newlib */      if (errno == EINTR)          continue;      perror("shm unlock");      _CPU_Fatal_halt( 0xdead0006 );    }  }}#endif

⌨️ 快捷键说明

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