2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Lock a semaphore.
8 #include "exec_intern.h"
9 #include "semaphores.h"
10 #include <exec/semaphores.h>
11 #include <aros/atomic.h>
13 #include <proto/exec.h>
15 #define CHECK_INITSEM 1
17 /*****************************************************************************/
24 #include <proto/exec.h>
26 AROS_LH1(void, ObtainSemaphore
,
29 AROS_LHA(struct SignalSemaphore
*, sigSem
, A0
),
32 struct ExecBase
*, SysBase
, 94, Exec
)
35 Obtain an exclusive lock on a semaphore. If the semaphore is already
36 in use by another task this function will wait until the semaphore
40 sigSem - Pointer to semaphore structure
45 This function preserves all registers.
56 *****************************************************************************/
61 AROS_LIBBASE_EXT_DECL(struct ExecBase
*,SysBase
)
65 /* Get pointer to current task */
69 if (sigSem
->ss_Link
.ln_Type
!= NT_SIGNALSEM
)
71 kprintf("\n\nObtainSemaphore called on a not intialized semaphore!!! "
72 "sem = %x task = %x (%s)\n\n", sigSem
, me
, me
->tc_Node
.ln_Name
);
77 /* Arbitrate for the semaphore structure */
81 ss_QueueCount == -1 indicates that the semaphore is
82 free, so we increment this straight away. If it then
83 equals 0, then we are the first to allocate this semaphore.
85 Note: This will need protection for SMP machines.
87 sigSem
->ss_QueueCount
++;
88 if( sigSem
->ss_QueueCount
== 0 )
90 /* We now own the semaphore. This is quick. */
91 sigSem
->ss_Owner
= me
;
92 sigSem
->ss_NestCount
++;
95 /* The semaphore was in use, but was it by us? */
96 else if( sigSem
->ss_Owner
== me
)
98 /* Yes, just increase the nesting count */
99 sigSem
->ss_NestCount
++;
103 Else, some other task must own it. We have
104 to set a waiting request here.
109 We need a node to mark our semaphore request. Lets use some
112 struct SemaphoreRequest sr
;
116 Have to clear the signal to make sure that we don't
117 return immediately. We then add the SemReq to the
118 waiters list of the semaphore. We were the last to
119 request, so we must be the last to get the semaphore.
122 #warning This must be atomic!
123 AROS_ATOMIC_AND(me
->tc_SigRecvd
, ~SIGF_SINGLE
);
125 AddTail((struct List
*)&sigSem
->ss_WaitQueue
, (struct Node
*)&sr
);
128 Finally, we simply wait, ReleaseSemaphore() will fill in
129 who owns the semaphore.
138 } /* ObtainSemaphore */