Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include<menuet/os.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<menuet/sem.h>
  5. #include<menuet/thread.h>
  6. #include<assert.h>
  7.  
  8. #define MAX_THREADS             128
  9.  
  10. typedef struct
  11. {
  12.  int flags;
  13.  void (* fn_ptr)(void);
  14.  void * thr_stack;
  15.  int pid;
  16. } thread_t;
  17.  
  18. static thread_t * thr[MAX_THREADS];
  19. DECLARE_STATIC_SEM(thr_list_sem);
  20.  
  21. static void do_thr_atexit(void);
  22.  
  23. void init_threads(void)
  24. {
  25.  register int i;
  26.  sem_lock(&thr_list_sem);
  27.  for(i=0;i<MAX_THREADS;i++) thr[i]=NULL;
  28.  sem_unlock(&thr_list_sem);
  29.  atexit(do_thr_atexit);
  30. }
  31.  
  32. int get_thread_pid(int tid)
  33. {
  34.  sem_lock(&thr_list_sem);
  35.  if(tid>=0 && tid<MAX_THREADS && thr[tid])
  36.  {
  37.   sem_unlock(&thr_list_sem);
  38.   return thr[tid]->pid;
  39.  }
  40.  sem_unlock(&thr_list_sem);
  41.  return -1;
  42. }
  43.  
  44. int get_thread_tid(int pid)
  45. {
  46.  register int i;
  47.  sem_lock(&thr_list_sem);
  48.  for(i=0;i<MAX_THREADS;i++)
  49.  {
  50.   if(thr[i] && thr[i]->pid==pid)
  51.   {
  52.    sem_unlock(&thr_list_sem);
  53.    return i;
  54.   }
  55.  }
  56.  sem_unlock(&thr_list_sem);
  57.  return -1;
  58. }
  59.  
  60. static void do_thr_atexit(void)
  61. {
  62.  register int i;
  63.  sem_lock(&thr_list_sem);
  64.  for(i=0;i<MAX_THREADS;i++)
  65.  {
  66.   if(thr[i] && (thr[i]->flags & THR_ATEXIT))
  67.   {
  68.    __asm__ __volatile__("int $0x40"::"a"(18),"b"(2),"c"(thr[i]->pid));
  69.    free(thr[i]->thr_stack);
  70.    free(thr[i]);
  71.    thr[i]=NULL;
  72.   }
  73.  }
  74.  sem_unlock(&thr_list_sem);
  75. }
  76.  
  77. int create_thread(void (* fn)(void),int stacksize,int flags,void ** rstackp)
  78. {
  79.  int i;
  80.  if(stacksize<4096) stacksize=4096;
  81.  sem_lock(&thr_list_sem);
  82.  for(i=0;i<MAX_THREADS;i++)
  83.  {
  84.   if(!thr[i])
  85.   {
  86.    thr[i]=(thread_t *)malloc(sizeof(thread_t));
  87.    thr[i]->thr_stack=malloc(stacksize);
  88.    if(!thr[i]->thr_stack)
  89.    {
  90.     free(thr[i]);
  91.     thr[i]=NULL;
  92.     sem_unlock(&thr_list_sem);
  93.     return -1;
  94.    }
  95.    thr[i]->flags=flags;
  96.    thr[i]->fn_ptr=fn;
  97.    __asm__ __volatile__("int $0x40":"=a"(thr[i]->pid)
  98.                       :"a"(51),"b"(1),"c"(fn),"d"(thr[i]->thr_stack+stacksize)
  99.           );
  100.    if(thr[i]->pid==-1)
  101.    {
  102.     free(thr[i]);
  103.     thr[i]=NULL;
  104.     sem_unlock(&thr_list_sem);
  105.     return -1;
  106.    }
  107.    sem_unlock(&thr_list_sem);
  108.    return i;
  109.   }
  110.  }
  111.  sem_unlock(&thr_list_sem);
  112.  return -1;
  113. }
  114.  
  115. void kill_thread(int tid)
  116. {
  117.  assert(tid<0);
  118.  assert(tid>=MAX_THREADS);
  119.  assert(get_thread_pid(tid)<0);
  120.  assert(!thr[tid]);
  121.  sem_lock(&thr_list_sem);
  122.  if(thr[tid]->flags & THR_KILLER)
  123.  {
  124.   thr[tid]->flags=0;
  125.   sem_unlock(&thr_list_sem);
  126.   do_thr_atexit();
  127.   exit(0);  
  128.   }
  129.  __asm__ __volatile__("int $0x40"::"a"(18),"b"(2),"c"(thr[tid]->pid));
  130. }
  131.