home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / quartz / quartz10.lha / src / presto / shbrk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  6.6 KB  |  306 lines

  1. /* $Copyright:    $
  2.  * Copyright (c) 1984, 1985, 1986 Sequent Computer Systems, Inc.
  3.  * All rights reserved
  4.  *  
  5.  * This software is furnished under a license and may be used
  6.  * only in accordance with the terms of that license and with the
  7.  * inclusion of the above copyright notice.   This software may not
  8.  * be provided or otherwise made available to, or used by, any
  9.  * other person.  No title to or ownership of the software is
  10.  * hereby transferred.
  11.  */
  12.  
  13. #ifndef    lint
  14. static    char    rcsid[] = "$Header: shbrk.c 1.3 88/03/31 $";
  15. #endif
  16.  
  17. /*
  18.  * shbrk.c
  19.  *    Parallel run-time basic shared memory allocator.
  20.  *
  21.  * Heavily based on Sequent parallel programming library shared memory
  22.  * manager.  Greatly simplified.
  23.  */
  24.  
  25. /* $Log:    shbrk.c,v $
  26.  * Revision 1.3  88/03/31  15:39:43  rbk
  27.  * Drop all refs to "do_shared_stack" (not necessary, and value was 0).
  28.  * Also drop all refs to _single_stack -- not needed, since signal handling
  29.  * much simpler than microtasking code (child processes don't trap signals).
  30.  * _init_shstk() is now a NOP since not using the microtasking library's
  31.  * "shared stack"; drop other junk dealing with this shared stack
  32.  * (misc #define's, variables, grow_stack()).
  33.  * Other simplifications for simpler environment.
  34.  * 
  35.  * Revision 1.2  88/03/24  09:52:32  rbk
  36.  * Import MMAP macro, drop #include of parc.h.  Also #unifdef -DCONCAT.
  37.  * 
  38.  * Revision 1.1  88/03/22  15:23:28  rbk
  39.  * Initial revision
  40.  * 
  41.  */
  42.  
  43. #ifdef sequent
  44.  
  45. #include <sys/types.h>
  46. #include <sys/errno.h>
  47. #include <sys/file.h>
  48. #include <sys/mman.h>
  49. #include <sys/signal.h>
  50.  
  51. #include <parallel/parallel.h>
  52.  
  53. #define    MMAP(fd,va,sz,pos)    \
  54.         mmap(va, sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, pos)
  55.  
  56. /*
  57.  * Module local variables.
  58.  */
  59.  
  60. private    int    priv_stack_limit;        /* size limit for priv stack */
  61. private    static    char    *myshbrk;        /* process local max sbrk */
  62. shared    static    char    *curshbrk;        /* global for all processes */
  63. shared    static    slock_t    shbrk_lock = L_UNLOCKED;
  64.  
  65. /*
  66.  * _init_shbrk()
  67.  *    Initialize basic shared-memory allocator.
  68.  *
  69.  * Called from _ppinit().
  70.  *
  71.  * Since the memory manager comes into play on a SEGV signal, we have to be
  72.  * careful that we don't get preempted at any point from within this handler,
  73.  * since the "state" represented by the fp and sp are transient.  This routine
  74.  * must be allowed to finish without interruption.
  75.  *
  76.  * We also block the SIGUSR1 and SIGVTALRM signals (SIGUSR1 and SIGVTALRM
  77.  * are used by preemption code).
  78.  */
  79.  
  80. static int    segvh();
  81.  
  82. static struct sigvec vec =  {
  83.     segvh, 
  84.     sigmask(SIGSEGV)|sigmask(SIGCHLD)|sigmask(SIGUSR1)|sigmask(SIGVTALRM),
  85.     1
  86. };
  87.  
  88. extern    void    enable_interrupts();
  89. extern    int    disable_interrupts();
  90.  
  91. static    private    int    reenable_interrupts = 0;
  92.  
  93. #define DISABLE_INTERRUPTS()  {reenable_interrupts = disable_interrupts();}
  94. #define ENABLE_INTERRUPTS()   {if (reenable_interrupts) enable_interrupts();}
  95.  
  96. private    static    int    segvstack[512];
  97. private    static    struct    sigstack sigstruct = {(caddr_t)&segvstack[511], 0};
  98.  
  99. int    sigstack();
  100. char    *getenv();
  101.  
  102. _init_shbrk()
  103. {
  104.     extern    shared char _shend_;
  105.  
  106.     /*
  107.      * Set up SIGSEGV handler; catch signal and grow shared-data
  108.      * and shared stack if appropriate.
  109.      */
  110.  
  111.     (void) sigstack(&sigstruct, (struct sigstack *)0);
  112.     (void) sigvec(SIGSEGV, &vec, (struct sigvec *)0);
  113.  
  114.     /*
  115.      * Initialize state variables.
  116.      */
  117.  
  118.     curshbrk = myshbrk = &_shend_;
  119.     return(0);
  120. }
  121.  
  122. /*
  123.  * shsbrk()
  124.  *    shared-memory sbrk(); create new shared space, return start address.
  125.  */
  126.  
  127. char *
  128. shsbrk(incr)
  129.     int    incr;
  130. {
  131.     register slock_t *spin_ptr = &shbrk_lock;
  132.     char    *val;
  133.  
  134.     if (incr == 0)
  135.         return(curshbrk);    /* note: can race with others! */
  136.  
  137.     if (incr < 0) {            /* can't shrink */
  138.         errno = EINVAL;
  139.         return((char *) -1);
  140.     }
  141.  
  142.     /*
  143.      * Lock data-file to insure one shared-brk at a time (and
  144.      * stable value of curshbrk).
  145.      */
  146.  
  147.     DISABLE_INTERRUPTS();
  148.     S_LOCK(spin_ptr);
  149.  
  150.     val = curshbrk;
  151.     if (lshbrk(val + incr) < 0)
  152.         val = (char *) -1;
  153.  
  154.     S_UNLOCK(spin_ptr);
  155.     ENABLE_INTERRUPTS();    
  156.     return(val);
  157. }
  158.  
  159. /*
  160.  * shbrk()
  161.  *    Add shared address space, analogous to brk().
  162.  *
  163.  * Just front-end to lshbrk() -- lock file and try to grow.
  164.  */
  165.  
  166. shbrk(newbrk)
  167.     char    *newbrk;
  168. {
  169.     register slock_t *spin_ptr = &shbrk_lock;
  170.     int    val;
  171.  
  172.     DISABLE_INTERRUPTS();
  173.     S_LOCK(spin_ptr);
  174.  
  175.     val = lshbrk(newbrk);
  176.  
  177.     S_UNLOCK(spin_ptr);
  178.     ENABLE_INTERRUPTS();
  179.     return(val);
  180. }
  181.  
  182. /*
  183.  * lshbrk()
  184.  *    "Locked" shbrk().  Internal procedure.
  185.  *
  186.  * Assumes caller locked shmem file, to serialize access to this code.
  187.  * No need to check if running into bottom of UNIX private stack since
  188.  * threads run on their own stacks.
  189.  */
  190.  
  191. static
  192. lshbrk(newbrk)
  193.     register char    *newbrk;
  194. {
  195.     register char    *cur;            /* actual brk (rounded) */
  196.     register char    *new;            /* requested brk (rounded) */
  197.     extern    shared char    _shstart_;    /* start of shared stuff */
  198.  
  199.     /*
  200.      * Not allowed to shrink self (yet).
  201.      */
  202.  
  203.     if (newbrk < myshbrk) {
  204.         errno = EINVAL;
  205.         return(-1);
  206.     }
  207.  
  208.     /*
  209.      * Growing: if no actual increase (rounding/etc), just adjust
  210.      * (self) myshbrk.
  211.      */
  212.  
  213.     cur = PGRND(myshbrk);
  214.     if (cur >= newbrk) {
  215.         myshbrk = newbrk;
  216.         if (newbrk > curshbrk)
  217.             curshbrk = myshbrk;
  218.         return(0);
  219.     }
  220.     new = PGRND(newbrk);
  221.  
  222.     /*
  223.      * Need to mmap() more of file.
  224.      */
  225.  
  226.     if (MMAP(_shm_fd, cur, new - cur, cur - &_shstart_) < 0) {
  227.         errno = ENOMEM;
  228.         return(-1);
  229.     }
  230.  
  231.     myshbrk = newbrk;        /* maybe not aligned */
  232.     if (newbrk > curshbrk)
  233.         curshbrk = newbrk;    /* grew the global memory */
  234.  
  235.     return(0);            /* success! */
  236. }
  237.  
  238. /*
  239.  * _init_shstk()
  240.  *    Initialize microtasking shared-stack.
  241.  *
  242.  * Called from _ppinit().
  243.  */
  244.  
  245. int *
  246. _init_shstk(ctxt_bottom, ctxt_top)
  247.     int    *ctxt_bottom;
  248.     int    *ctxt_top;
  249. {
  250.     /*
  251.      * NOP -- never called since not using "microtask shared stack".
  252.      */
  253.     return(0);
  254. }
  255.  
  256. /*
  257.  * segvh()
  258.  *    SIGSEGV handler.
  259.  *
  260.  * If process isn't up to max shared-data, get there and re-try the
  261.  * instruction.  Else turn off handler and retry (==> dump core).
  262.  */
  263.  
  264. /*ARGSUSED*/
  265. static
  266. segvh(sig, code, scp)
  267.     int sig, code;
  268.     struct sigcontext *scp;
  269. {
  270.     register slock_t *spin_ptr = &shbrk_lock;
  271.     register int *fa = (int *)code;
  272.  
  273.     /*
  274.      * A signal code of -1 indicates the signal originated from a
  275.      * kill() system call, rather than a real program fault.
  276.      */
  277.  
  278.     if (fa == (int *)-1) {
  279.         (void) signal(SIGSEGV, SIG_DFL);
  280.         (void) kill(getpid(), SIGSEGV);
  281.         return;
  282.     }
  283.  
  284.     /*
  285.      * If process doesn't have all of shared heap mapped, map it and retry.
  286.      * Otherwise turn off SIGSEGV handling.
  287.      *
  288.      * Lock data-file during this to stabilize curshbrk and
  289.      * insure only one lshbrk() at a time.
  290.      *
  291.      * Return retries instruction, will die for real if turn off
  292.      * signal handling here.
  293.      */
  294.  
  295.     DISABLE_INTERRUPTS();
  296.     S_LOCK(spin_ptr);
  297.  
  298.     if (myshbrk >= curshbrk || lshbrk(curshbrk) < 0)
  299.         (void) signal(SIGSEGV, SIG_DFL);
  300.  
  301.     S_UNLOCK(spin_ptr);
  302.     ENABLE_INTERRUPTS();
  303. }
  304.  
  305. #endif sequent
  306.