home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / thread.c < prev    next >
C/C++ Source or Header  |  1992-09-05  |  3KB  |  118 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 "lib.h"
  25.  
  26. #define SIZE 4096L
  27.  
  28. extern int __mint;
  29. extern long _childtime;            /* in main.c */
  30. extern long _sigpending, _sigmask;    /* in signal.c */
  31. extern __Sigfunc _sig_handler[NSIG];    /* ditto */
  32.  
  33.  
  34. /* this is used by wait() and wait3() to retrieve the child's exit code */
  35. long __waitval = -ENOENT;
  36.  
  37. /* and this is used to retrieve the child's time */
  38. long __waittime = 0;
  39.  
  40. static void __CDECL
  41. startup(b)
  42.     register BASEPAGE *b;
  43. {
  44.     register int (*func) __PROTO((long));
  45.     register long arg;
  46.     extern void _setstack();    /* in crt0.s */
  47.  
  48. #ifdef __TURBOC__
  49.     extern void *_StkLim;    /* avoid stack checking */
  50.     _StkLim = NULL;
  51. #endif
  52.     _setstack( ((char *)b) + SIZE );
  53.     func = (int (*) __PROTO((long)))b->p_dbase;
  54.     arg = b->p_dlen;
  55.     Pterm((*func)(arg));
  56. }
  57.  
  58. /* use long instead of int so vfork works OK with -mshort */
  59.  
  60. long
  61. tfork(func, arg)
  62.     int (*func) __PROTO((long));
  63.     long arg;
  64. {
  65.     register BASEPAGE *b;
  66.     register long pid;
  67.     register long savpending, savmask;
  68.     register BASEPAGE *savbase;
  69.     __Sigfunc savhandler[NSIG];
  70.     long now;
  71.     int i;
  72.  
  73.     b = (BASEPAGE *)Pexec(PE_CBASEPAGE, 0L, "", 0L);
  74.     (void)Mshrink(b, SIZE+256);
  75.     b->p_tbase = (char *)startup;
  76.     b->p_dbase = (char *)func;
  77.     b->p_dlen = arg;
  78.     b->p_hitpa = ((char *)b) + SIZE + 256;
  79.  
  80.     if (__mint)
  81.         pid = Pexec(104, 0L, b, 0L);
  82.     else {
  83.     /* save the signal masks and signal handlers, the child may change
  84.            them */
  85.         savpending = _sigpending;
  86.         _sigpending = 0;
  87.         savmask = _sigmask;
  88.         _sigmask = 0;
  89.         for (i = 0; i < NSIG; i++)
  90.             savhandler[i] = _sig_handler[i];
  91.         savbase = _base;
  92.         _base = b;
  93.  
  94.         now = clock();
  95.         pid = Pexec(4, 0L, b, 0L);
  96.         (void)Mfree(b->p_env);    /* free the memory */
  97.         (void)Mfree(b);
  98.  
  99.         _base = savbase;
  100.     /* restore signal stuff */
  101.         for (i = 0; i < NSIG; i++)
  102.             _sig_handler[i] = savhandler[i];
  103.         _sigmask = savmask;
  104.         _sigpending = savpending;
  105.         if (pid >= 0) {
  106.             long retval = pid;
  107.  
  108.         /* see the TOS algorithm for getpid() */
  109.             pid = ((long)b) >> 8;
  110.             __waitval = (pid << 16) | retval;
  111.             raise(SIGCHLD);
  112.             __waittime = clock() - now;
  113.             _childtime += __waittime;
  114.         }
  115.     }
  116.     return pid;
  117. }
  118.