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

📄 sys_arch.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  struct thread_start_param *thread_param;  pthread_attr_t attr;  thread = sys_malloc(sizeof(struct sys_thread));  if(thread != NULL){    thread->next = threads;    SET(thread->flags, 0x00);    thread->stack = (char *) sys_malloc(sizeof(char)*THREAD_STACK_SIZE);    thread->timeouts = NULL;#ifdef THREAD_DEBUG    thread->name = (char *) sys_malloc(20);    bcopy(name, thread->name, name_len);#endif    if(thread->stack == NULL){      sys_free(thread);      rtl_printf("ERROR: Not enough memory to create new thread's stack\n");      return NULL;    }    threads = thread;    pthread_attr_init(&attr);    /* Because it's a thread which is trying to create another thread, RTLinux       only allows that by passing to the new thread it's stack */        pthread_attr_setstackaddr(&attr, thread->stack);    pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);        thread_param = sys_malloc(sizeof(struct thread_start_param));        if(thread_param == NULL){      sys_free(thread->stack);      sys_free(thread);      rtl_printf("ERROR: Not enough memory to create thread start param\n");      return NULL;    }        thread_param->function = function;    thread_param->arg = arg;    thread_param->thread = thread;        if(pthread_create(&(thread->pthread),&attr, thread_start, thread_param)) {      rtl_printf("\nsys_thread_new: pthread_create  0x%x 0x%x\n", pthread_self(),thread->pthread);      rtl_printf("Kernel Panic\n");      return NULL;    }    if(period != 0)      pthread_make_periodic_np(thread->pthread, gethrtime(), period);    return (void *) thread->pthread;  }    rtl_printf("ERROR: Not enough memory to create thread\n");   return NULL;}/*-----------------------------------------------------------------------------------*/struct sys_mbox *sys_mbox_new(){  struct sys_mbox *mbox;  mbox = sys_malloc(sizeof(struct sys_mbox));  if(mbox != NULL){        mbox->first = mbox->last = 0;    mbox->mail = sys_sem_new_(0);    mbox->mutex = sys_sem_new_(1);    return mbox;  }else{    rtl_printf("ERROR: Not enough memory to create mbox\n");    return NULL;  }}/*-----------------------------------------------------------------------------------*/voidsys_mbox_free(struct sys_mbox *mbox){  if(mbox != SYS_MBOX_NULL) {    sys_sem_wait(mbox->mutex);        sys_sem_free(mbox->mail);    sys_sem_free(mbox->mutex);    mbox->mail = mbox->mutex = NULL;    sys_free(mbox);  }}/*-----------------------------------------------------------------------------------*/voidsys_mbox_post(struct sys_mbox *mbox, void *msg){  u8_t first;  unsigned int state;  sys_sem_wait(mbox->mutex);    mbox->msgs[mbox->last] = msg;  if(mbox->last == mbox->first) {    first = 1;  } else {    first = 0;  }    mbox->last++;  if(mbox->last == SYS_MBOX_SIZE) {    mbox->last = 0;  }  sys_stop_interrupts(&state);    if(first)    sys_sem_signal_pre(mbox->mail);  sys_sem_signal(mbox->mutex);    sys_allow_interrupts(&state);}/*-----------------------------------------------------------------------------------*/u16_tsys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u16_t timeout){  u16_t time = 1;    /* The mutex lock is quick so we don't bother with the timeout     stuff here. */  sys_arch_sem_wait(mbox->mutex, 0);  while(mbox->first == mbox->last) {    sys_sem_signal(mbox->mutex);    /* We block while waiting for a mail to arrive in the mailbox. We       must be prepared to timeout. */    if(timeout != 0) {      time = sys_arch_sem_wait(mbox->mail, timeout);            /* If time == 0, the sem_wait timed out, and we return 0. */      if(time == 0) {	return 0;      }    } else      sys_arch_sem_wait(mbox->mail, 0);    sys_arch_sem_wait(mbox->mutex, 0);  }    if(msg != NULL) {    *msg = mbox->msgs[mbox->first];  }    mbox->first++;  if(mbox->first == SYS_MBOX_SIZE) {    mbox->first = 0;  }        sys_sem_signal(mbox->mutex);    return time;}/*-----------------------------------------------------------------------------------*/struct sys_sem *sys_sem_new(u8_t count){  return sys_sem_new_(count);}/*-----------------------------------------------------------------------------------*/static struct sys_sem *sys_sem_new_(u8_t count){  struct sys_sem *sem;  sem = sys_malloc(sizeof(struct sys_sem));  if(sem != NULL){    sem->c = count;    sem_init(&(sem->sem),0,count);    return sem;  }else{    rtl_printf("ERROR: Not enough memory to create semaphore\n");    return NULL;  }}/*-----------------------------------------------------------------------------------*/static u16_t wait_for_semaphore(struct sys_sem *sem, u16_t timeout){  unsigned int tdiff;  unsigned long sec, usec;  struct timeval rtime1, rtime2;  struct timespec ts;  struct timezone tz;  int retval;  if(timeout > 0) {    /* Get a timestamp and add the timeout value. */    gettimeofday(&rtime1, &tz);    sec = rtime1.tv_sec;    usec = rtime1.tv_usec;    usec += timeout % 1000 * 1000;      sec += (int)(timeout / 1000) + (int)(usec / 1000000);    usec = usec % 1000000;    ts.tv_nsec = usec * 1000;    ts.tv_sec = sec;     retval = sem_timedwait(&(sem->sem),&ts);       if(retval == -1) {      return 0;    } else {      /* Calculate for how long we waited for the cond. */      gettimeofday(&rtime2, &tz);      tdiff = (rtime2.tv_sec - rtime1.tv_sec) * 1000 +		(rtime2.tv_usec - rtime1.tv_usec) / 1000;      if(tdiff == 0) {	return 1;      }      return tdiff;    }  } else {    sem_wait(&(sem->sem));    return 0;  }}/*-----------------------------------------------------------------------------------*/u16_tsys_arch_sem_wait(struct sys_sem *sem, u16_t timeout){  u16_t time = 1;  sem->sem.value = sem->c;  while(sem->c <= 0) {        if(timeout > 0) {      time = wait_for_semaphore(sem, timeout);      if(time == 0) 	return 0;    } else {      wait_for_semaphore(sem,0);    }  }  sem->c--;  sem->sem.value = sem->c;  return time;}/*-----------------------------------------------------------------------------------*/intsys_sem_signal(struct sys_sem *sem){  sem->c++;  if(sem->c > 1)    sem->c = 1;  sem->sem.value = sem->c;  return sys_sem_post(&(sem->sem));}/*-----------------------------------------------------------------------------------*/voidsys_sem_free(struct sys_sem *sem){  if(sem != NULL)    sem_destroy(&(sem->sem));  sys_free(sem);}/*-----------------------------------------------------------------------------------*/void sys_arch_close(void){  struct sys_thread *st;  for(st = threads; st != NULL; st = st->next) {    if(AND(st->flags,0x81)== 0x80){ //i.e. It is a standalone thread finished      sys_free(st->stack);    }else if(AND(st->flags,0xff)==0x00){ //i.e A thread still working      pthread_delete_np(st->pthread);      //This line is necessary because the thread could be standalone.      //If it is not, nothing happens      sys_free(st->stack);                   }else if(AND(st->flags,0xff)==0x01){ //i.e A registered thread still working      pthread_cancel(st->pthread);      pthread_join(st->pthread,NULL);    }  }  free_all_resources();  return;}/*-----------------------------------------------------------------------------------*/voidsys_init(void){  int i,retval;  for(i=0; i<=500; i++)    mallocs[i] = NULL;  for(i=0; i<MAX_TIMERS; i++){    vector_of_timers[i].signal = RTL_SIGRTMIN + signal++;    vector_of_timers[i].timer_event_spec.sigev_notify = SIGEV_SIGNAL;    vector_of_timers[i].timer_event_spec.sigev_signo = vector_of_timers[i].signal;    vector_of_timers[i].timer_event_spec.sigev_value.sival_int = 13;        retval = timer_create(CLOCK_REALTIME, &(vector_of_timers[i].timer_event_spec), &(vector_of_timers[i].timer));        if (retval) {      rtl_printf("timer_create(CLOCK_REALTIME) failed:\n");    }  }}/*-----------------------------------------------------------------------------------*/voidsys_sem_wait(sys_sem_t sem){  sys_arch_sem_wait(sem, 0);}/*-----------------------------------------------------------------------------------*/int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout){  return sys_arch_sem_wait(sem, timeout);}/*-----------------------------------------------------------------------------------*/voidsys_mbox_fetch(sys_mbox_t mbox, void **msg){  sys_arch_mbox_fetch(mbox, msg, 0);}/*-----------------------------------------------------------------------------------*/void sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg){  struct sys_thread *thread;  int err, sec = 0, nsec = 0;  thread = sys_current_thread();  if(thread->timeouts == NULL){    thread->timeouts = &vector_of_timers[timer_index++];  }  thread->timeouts->sa.sa_handler = h;  thread->timeouts->sa.sa_mask=0;  thread->timeouts->sa.sa_flags=0;  thread->timeouts->sa.sa_focus=0;  rtl_sigemptyset(&(thread->timeouts->sa.sa_mask));  if (sigaction(thread->timeouts->signal, &(thread->timeouts->sa), NULL)) {    rtl_printf("sigaction failed");  }    if(msecs >= 100){    sec = msecs / 1000;    nsec = (msecs % 1000) * 1000000 ;  }else{    nsec = msecs * 1000000;  }  thread->timeouts->ospec.it_value.tv_sec = sec;  thread->timeouts->ospec.it_value.tv_nsec = nsec;  thread->timeouts->ospec.it_interval.tv_sec = 0;  thread->timeouts->ospec.it_interval.tv_nsec = 0;  err = timer_settime(thread->timeouts->timer, 0, &(thread->timeouts->ospec), &(thread->timeouts->old_setting));  return;  }/*-----------------------------------------------------------------------------------*/void sys_untimeout(sys_timeout_handler h, void *arg){  struct sys_thread *thread;  thread = sys_current_thread();  if(thread->timeouts != NULL)    timer_delete(thread->timeouts->timer);}

⌨️ 快捷键说明

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