clean the code a little by reducing amout of places where gcc decides to put ud2...
[AROS.git] / rom / exec / alloctrap.c
blob76afd2ae1d2f380fccc02ed61e98213e409bdad1
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Allocate a trap
6 Lang: english
7 */
8 #include "exec_intern.h"
9 #include <proto/exec.h>
11 /*****************************************************************************
13 NAME */
15 AROS_LH1(LONG, AllocTrap,
17 /* SYNOPSIS */
18 AROS_LHA(long, trapNum, D0),
20 /* LOCATION */
21 struct ExecBase *, SysBase, 57, Exec)
23 /* FUNCTION
25 INPUTS
27 RESULT
29 NOTES
31 EXAMPLE
33 BUGS
35 SEE ALSO
37 INTERNALS
38 Very similar to AllocSignal()
40 *****************************************************************************/
42 AROS_LIBFUNC_INIT
44 struct Task *ThisTask = GET_THIS_TASK;
45 UWORD mask;
46 UWORD mask1;
48 if (ThisTask)
50 mask = GetTrapAlloc(ThisTask);
52 /* Will any trap do? */
53 if(trapNum < 0)
56 * To get the last nonzero bit in a number I use a&~a+1:
57 * Given a number that ends with a row of zeros xxxx1000
58 * I first toggle all bits in that number XXXX0111
59 * then add 1 to toggle all but the last 0 again XXXX1000
60 * and AND this with the original number 00001000
62 * And since ~a+1=-a I can use a&-a instead.
64 * And to get the last zero bit I finally use ~a&-~a.
66 mask1 = ~mask & - ~mask;
68 /* Is the bit already allocated? */
69 if(mask1 == 0)
70 return -1;
72 /* And get the bit number */
73 trapNum = (mask1 & 0xff00 ? 8 : 0) + (mask1 & 0xf0f0 ? 4 : 0) +
74 (mask1 & 0xcccc ? 2 : 0) + (mask1 & 0xaaaa ? 1 : 0);
76 else
78 mask1 = 1 << trapNum;
80 /* If trap bit is already allocated, return. */
81 if(mask & mask1)
82 return -1;
85 if (ThisTask->tc_Flags & TF_ETASK) {
86 struct ETask *et = ThisTask->tc_UnionETask.tc_ETask;
88 et->et_TrapAlloc |= mask1;
89 } else
90 ThisTask->tc_TrapAlloc |= mask1;
93 return trapNum;
94 AROS_LIBFUNC_EXIT
95 } /* AllocTrap() */