home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / MT / BEGINTHR.C next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  2.1 KB  |  95 lines

  1. /* beginth.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
  2.  
  3. #include <sys/emx.h>
  4. #include <stdlib.h>
  5. #include <errno.h>
  6. #include <os2emx.h>
  7.  
  8. #define MAX_THREADS 1024
  9.  
  10. static struct _thread thread_1 =
  11. {
  12.   0,                            /* _th_errno */
  13.   NULL,                         /* _th_arg */
  14.   NULL,                         /* _th_start */
  15.   NULL,                         /* _th_strtok_ptr (must be NULL) */
  16.   {0},                          /* _th_asctime_buf */
  17.   {0},                          /* _th_tmpnam_buf */
  18.   {0}                           /* _th_gmtime_buf */
  19. };
  20.  
  21. struct _thread *_thread_tab[MAX_THREADS+1] = {NULL, &thread_1};
  22.  
  23.  
  24. static void start_thread (struct _thread *tp)
  25. {
  26.   tp->_th_start (tp->_th_arg);
  27.   _endthread();
  28. }
  29.  
  30.  
  31. int _beginthread (void (*start)(void *arg), void *stack, unsigned stack_size,
  32.                   void *arg_list)
  33. {
  34.   ULONG rc;
  35.   TID tid;
  36.   struct _thread *tp;
  37.  
  38.   rc = DosAllocMem ((PPVOID)&tp, sizeof (struct _thread),
  39.                     PAG_COMMIT|PAG_READ|PAG_WRITE);
  40.   if (rc != 0)
  41.     {
  42.       errno = ENOMEM;
  43.       return (-1);
  44.     }
  45.   tp->_th_start = start;
  46.   tp->_th_arg = arg_list;
  47.   rc = DosCreateThread (&tid, (PFNTHREAD)start_thread, (ULONG)tp,
  48.                         3, stack_size);
  49.   if (rc != 0)
  50.     {
  51.       if (rc == ERROR_NOT_ENOUGH_MEMORY)
  52.         errno = ENOMEM;
  53.       else if (rc == ERROR_MAX_THRDS_REACHED)
  54.         errno = EAGAIN;
  55.       else
  56.         errno = EINVAL;
  57.       return (-1);
  58.     }
  59.   if (tid > MAX_THREADS)
  60.     {
  61.       DosKillThread (tid);
  62.       errno = EAGAIN;
  63.       return (-1);
  64.     }
  65.   if (__newthread (tid) != 0)
  66.     {
  67.       DosKillThread (tid);
  68.       return (-1);
  69.     }
  70.   _thread_tab[tid] = tp;
  71.   rc = DosResumeThread (tid);
  72.   if (rc != 0)
  73.     {
  74.       errno = ESRCH;
  75.       return (-1);
  76.     }
  77.   return (tid);
  78. }
  79.  
  80.  
  81. void _endthread (void)
  82. {
  83.   struct _thread *tp;
  84.   int tid;
  85.  
  86.   tid = _tid ();
  87.   tp = _thread ();
  88.   if (tp != &thread_1)
  89.     DosFreeMem (tp);
  90.   _thread_tab[tid] = NULL;
  91.   __endthread (tid);
  92.   for (;;)
  93.     DosExit ((tid == 1 ? EXIT_PROCESS : EXIT_THREAD), 0);
  94. }
  95.