home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / thread.c < prev    next >
C/C++ Source or Header  |  1993-05-17  |  3KB  |  119 lines

  1. /*
  2.  * tfork(function, argument): starts a new thread of execution running
  3.  * in the same address space. The new thread gets its own 4K stack,
  4.  * and starts at the address in "function" with "argument" on the stack,
  5.  * i.e. as though the main program had a call like "function(argument)".
  6.  * The main program continues executing, with tfork returning the process
  7.  * i.d. of the child.
  8.  * (if MiNT is not active, then the child runs to completion
  9.  *  and the return value is the child's exit status; vfork() relies on
  10.  *  this behavior)
  11.  *
  12.  * Note that parent and child share the same memory; this could cause
  13.  * problems with some library calls, notably malloc().
  14.  */
  15.  
  16. #include <compiler.h>
  17. #include <osbind.h>
  18. #include <basepage.h>
  19. #include <signal.h>
  20. #include <time.h>
  21. #include <unistd.h>
  22. #include <signal.h>
  23. #include <errno.h>
  24. #include <support.h>
  25. #include "lib.h"
  26.  
  27. #define SIZE 4096L
  28.  
  29. extern int __mint;
  30. extern long _childtime;            /* in main.c */
  31. extern long _sigpending, _sigmask;    /* in signal.c */
  32. extern __Sigfunc _sig_handler[NSIG];    /* ditto */
  33.  
  34.  
  35. /* this is used by wait() and wait3() to retrieve the child's exit code */
  36. long __waitval = -ENOENT;
  37.  
  38. /* and this is used to retrieve the child's time */
  39. long __waittime = 0;
  40.  
  41. static void __CDECL
  42. startup(b)
  43.     register BASEPAGE *b;
  44. {
  45.     register int (*func) __PROTO((long));
  46.     register long arg;
  47.     extern void _setstack();    /* in crt0.s */
  48.  
  49. #ifdef __TURBOC__
  50.     extern void *_StkLim;    /* avoid stack checking */
  51.     _StkLim = NULL;
  52. #endif
  53.     _setstack( ((char *)b) + SIZE );
  54.     func = (int (*) __PROTO((long)))b->p_dbase;
  55.     arg = b->p_dlen;
  56.     Pterm((*func)(arg));
  57. }
  58.  
  59. /* use long instead of int so vfork works OK with -mshort */
  60.  
  61. long
  62. tfork(func, arg)
  63.     int (*func) __PROTO((long));
  64.     long arg;
  65. {
  66.     register BASEPAGE *b;
  67.     register long pid;
  68.     register long savpending, savmask;
  69.     register BASEPAGE *savbase;
  70.     __Sigfunc savhandler[NSIG];
  71.     long now;
  72.     int i;
  73.  
  74.     b = (BASEPAGE *)Pexec(PE_CBASEPAGE, 0L, "", 0L);
  75.     (void)Mshrink(b, SIZE+256);
  76.     b->p_tbase = (char *)startup;
  77.     b->p_dbase = (char *)func;
  78.     b->p_dlen = arg;
  79.     b->p_hitpa = ((char *)b) + SIZE + 256;
  80.  
  81.     if (__mint)
  82.         pid = Pexec(104, 0L, b, 0L);
  83.     else {
  84.     /* save the signal masks and signal handlers, the child may change
  85.            them */
  86.         savpending = _sigpending;
  87.         _sigpending = 0;
  88.         savmask = _sigmask;
  89.         _sigmask = 0;
  90.         for (i = 0; i < NSIG; i++)
  91.             savhandler[i] = _sig_handler[i];
  92.         savbase = _base;
  93.         _base = b;
  94.  
  95.         now = _clock();
  96.         pid = Pexec(4, 0L, b, 0L);
  97.         (void)Mfree(b->p_env);    /* free the memory */
  98.         (void)Mfree(b);
  99.  
  100.         _base = savbase;
  101.     /* restore signal stuff */
  102.         for (i = 0; i < NSIG; i++)
  103.             _sig_handler[i] = savhandler[i];
  104.         _sigmask = savmask;
  105.         _sigpending = savpending;
  106.         if (pid >= 0) {
  107.             long retval = pid;
  108.  
  109.         /* see the TOS algorithm for getpid() */
  110.             pid = ((long)b) >> 8;
  111.             __waitval = (pid << 16) | retval;
  112.             raise(SIGCHLD);
  113.             __waittime = _clock() - now;
  114.             _childtime += __waittime;
  115.         }
  116.     }
  117.     return pid;
  118. }
  119.