home *** CD-ROM | disk | FTP | other *** search
- /*
- (C) 1995-96 AROS - The Amiga Replacement OS
- $Id: allocsignal.c,v 1.8 1997/01/10 04:05:51 ldp Exp $
- $Log: allocsignal.c,v $
- Revision 1.8 1997/01/10 04:05:51 ldp
- Also clear alloc'ed bit from tc_SigExcept and tc_SigWait.
-
- Cache ThisTask in a local variable.
-
- Revision 1.7 1997/01/01 03:46:05 ldp
- Committed Amiga native (support) code
-
- Changed clib to proto
-
- Revision 1.6 1996/12/10 13:51:38 aros
- Moved all #include's in the first column so makedepend can see it.
-
- Revision 1.5 1996/10/24 15:50:44 aros
- Use the official AROS macros over the __AROS versions.
-
- Revision 1.4 1996/08/13 13:55:58 digulla
- Replaced AROS_LA by AROS_LHA
- Replaced some AROS_LH*I by AROS_LH*
- Sorted and added includes
-
- Revision 1.3 1996/08/01 17:41:05 digulla
- Added standard header for all files
-
- Desc:
- Lang:
- */
- #include <exec/execbase.h>
- #include <exec/tasks.h>
- #include <aros/libcall.h>
- #include <proto/exec.h>
-
- /*****************************************************************************
-
- NAME */
-
- AROS_LH1(BYTE, AllocSignal,
-
- /* SYNOPSIS */
- AROS_LHA(LONG, signalNum, D0),
-
- /* LOCATION */
- struct ExecBase *, SysBase, 55, Exec)
-
- /* FUNCTION
- Allocate a given signal out of the current task's pool of signals.
- Every task has a set of signals to communicate with other tasks.
- Half of them are reserved for the system and half of them is
- free for general use. Some of the reserved signals (e.g.
- SIGBREAKF_CTRL_C) have a defined behaviour and may be used by user
- code, however.
-
- INPUTS
- signalNum - Number of the signal to allocate or -1 if any signal
- will do.
-
- RESULT
- Number of the signal or -1 if the signal couldn't be allocated.
-
- NOTES
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
- FreeSignal(), Signal(), Wait()
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- AROS_LIBFUNC_INIT
-
- struct Task *ThisTask;
- ULONG *mask;
- ULONG mask1;
-
- /* Protect signal mask against possible task exceptions. */
- Forbid();
-
- ThisTask = SysBase->ThisTask;
-
- /* Get pointer to mask of allocated signal */
- mask=&ThisTask->tc_SigAlloc;
-
- /* Get signal */
- if(signalNum<0)
- {
- /* Any signal will do. */
-
- /*
- * To get the last nonzero bit in a number I use a&~a+1:
- * Given a number that ends with a row of zeros xxxx1000
- * I first toggle all bits in that number XXXX0111
- * then add 1 to toggle all but the last 0 again XXXX1000
- * and AND this with the original number 00001000
- *
- * And since ~a+1=-a I can use a&-a instead.
- *
- * And to get the last zero bit I finally use ~a&-~a.
- */
- mask1=~*mask&-~*mask;
-
- /* Got a bit? */
- if(mask1)
- {
- /* Allocate and reset the bit */
- *mask|=mask1;
- ThisTask->tc_SigRecvd &= ~mask1;
- ThisTask->tc_SigExcept &= ~mask1;
- ThisTask->tc_SigWait &= ~mask1;
-
- /* And get the bit number */
- signalNum=(mask1&0xffff0000?16:0)+(mask1&0xff00ff00?8:0)+
- (mask1&0xf0f0f0f0? 4:0)+(mask1&0xcccccccc?2:0)+
- (mask1&0xaaaaaaaa? 1:0);
- }
- }else
- {
- /* Get a specific signal */
- mask1=1<<signalNum;
-
- /* Check if signal is free */
- if(*mask&mask1)
- /* No. Return */
- signalNum=-1;
- else
- {
- /* It is free. Allocate and reset it. */
- *mask|=mask1;
- ThisTask->tc_SigRecvd &= ~mask1;
- ThisTask->tc_SigExcept &= ~mask1;
- ThisTask->tc_SigWait &= ~mask1;
- }
- }
-
- Permit();
-
- return signalNum;
- AROS_LIBFUNC_EXIT
- }
-
-