home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / exec / allocsignal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-10  |  3.4 KB  |  150 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: allocsignal.c,v 1.8 1997/01/10 04:05:51 ldp Exp $
  4.     $Log: allocsignal.c,v $
  5.     Revision 1.8  1997/01/10 04:05:51  ldp
  6.     Also clear alloc'ed bit from tc_SigExcept and tc_SigWait.
  7.  
  8.     Cache ThisTask in a local variable.
  9.  
  10.     Revision 1.7  1997/01/01 03:46:05  ldp
  11.     Committed Amiga native (support) code
  12.  
  13.     Changed clib to proto
  14.  
  15.     Revision 1.6  1996/12/10 13:51:38  aros
  16.     Moved all #include's in the first column so makedepend can see it.
  17.  
  18.     Revision 1.5  1996/10/24 15:50:44  aros
  19.     Use the official AROS macros over the __AROS versions.
  20.  
  21.     Revision 1.4  1996/08/13 13:55:58  digulla
  22.     Replaced AROS_LA by AROS_LHA
  23.     Replaced some AROS_LH*I by AROS_LH*
  24.     Sorted and added includes
  25.  
  26.     Revision 1.3  1996/08/01 17:41:05  digulla
  27.     Added standard header for all files
  28.  
  29.     Desc:
  30.     Lang:
  31. */
  32. #include <exec/execbase.h>
  33. #include <exec/tasks.h>
  34. #include <aros/libcall.h>
  35. #include <proto/exec.h>
  36.  
  37. /*****************************************************************************
  38.  
  39.     NAME */
  40.  
  41.     AROS_LH1(BYTE, AllocSignal,
  42.  
  43. /*  SYNOPSIS */
  44.     AROS_LHA(LONG, signalNum, D0),
  45.  
  46. /*  LOCATION */
  47.     struct ExecBase *, SysBase, 55, Exec)
  48.  
  49. /*  FUNCTION
  50.     Allocate a given signal out of the current task's pool of signals.
  51.     Every task has a set of signals to communicate with other tasks.
  52.     Half of them are reserved for the system and half of them is
  53.     free for general use. Some of the reserved signals (e.g.
  54.     SIGBREAKF_CTRL_C) have a defined behaviour and may be used by user
  55.     code, however.
  56.  
  57.     INPUTS
  58.     signalNum - Number of the signal to allocate or -1 if any signal
  59.             will do.
  60.  
  61.     RESULT
  62.     Number of the signal or -1 if the signal couldn't be allocated.
  63.  
  64.     NOTES
  65.  
  66.     EXAMPLE
  67.  
  68.     BUGS
  69.  
  70.     SEE ALSO
  71.     FreeSignal(), Signal(), Wait()
  72.  
  73.     INTERNALS
  74.  
  75.     HISTORY
  76.  
  77. ******************************************************************************/
  78. {
  79.     AROS_LIBFUNC_INIT
  80.  
  81.     struct Task *ThisTask;
  82.     ULONG *mask;
  83.     ULONG mask1;
  84.  
  85.     /* Protect signal mask against possible task exceptions. */
  86.     Forbid();
  87.  
  88.     ThisTask = SysBase->ThisTask;
  89.  
  90.     /* Get pointer to mask of allocated signal */
  91.     mask=&ThisTask->tc_SigAlloc;
  92.  
  93.     /* Get signal */
  94.     if(signalNum<0)
  95.     {
  96.     /* Any signal will do. */
  97.  
  98.     /*
  99.      * To get the last nonzero bit in a number I use a&~a+1:
  100.      * Given a number that ends with a row of zeros  xxxx1000
  101.      * I first toggle all bits in that number     XXXX0111
  102.      * then add 1 to toggle all but the last 0 again XXXX1000
  103.      * and AND this with the original number     00001000
  104.      *
  105.      * And since ~a+1=-a I can use a&-a instead.
  106.      *
  107.      * And to get the last zero bit I finally use ~a&-~a.
  108.      */
  109.     mask1=~*mask&-~*mask;
  110.  
  111.     /* Got a bit? */
  112.     if(mask1)
  113.     {
  114.         /* Allocate and reset the bit */
  115.         *mask|=mask1;
  116.         ThisTask->tc_SigRecvd  &= ~mask1;
  117.         ThisTask->tc_SigExcept &= ~mask1;
  118.         ThisTask->tc_SigWait   &= ~mask1;
  119.  
  120.         /* And get the bit number */
  121.         signalNum=(mask1&0xffff0000?16:0)+(mask1&0xff00ff00?8:0)+
  122.               (mask1&0xf0f0f0f0? 4:0)+(mask1&0xcccccccc?2:0)+
  123.               (mask1&0xaaaaaaaa? 1:0);
  124.     }
  125.     }else
  126.     {
  127.     /* Get a specific signal */
  128.     mask1=1<<signalNum;
  129.  
  130.     /* Check if signal is free */
  131.     if(*mask&mask1)
  132.         /* No. Return */
  133.         signalNum=-1;
  134.     else
  135.     {
  136.         /* It is free. Allocate and reset it. */
  137.         *mask|=mask1;
  138.         ThisTask->tc_SigRecvd  &= ~mask1;
  139.         ThisTask->tc_SigExcept &= ~mask1;
  140.         ThisTask->tc_SigWait   &= ~mask1;
  141.     }
  142.     }
  143.  
  144.     Permit();
  145.  
  146.     return signalNum;
  147.     AROS_LIBFUNC_EXIT
  148. }
  149.  
  150.