r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / exec / procure.c
blob381fb91c2a143bb26fd3a78a2b4de19186f2d117
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Try to lock a semaphore.
6 Lang: english
7 */
8 #include "exec_intern.h"
9 #include "semaphores.h"
10 #include <exec/semaphores.h>
11 #include <proto/exec.h>
13 /*****************************************************************************
15 NAME */
17 AROS_LH2(ULONG, Procure,
19 /* SYNOPSIS */
20 AROS_LHA(struct SignalSemaphore *, sigSem, A0),
21 AROS_LHA(struct SemaphoreMessage *, bidMsg, A1),
23 /* LOCATION */
24 struct ExecBase *, SysBase, 90, Exec)
26 /* FUNCTION
27 Tries to get a lock on a semaphore in an asynchronous manner.
28 If the semaphore is not free this function will not wait but
29 just post a request to the semaphore. As soon as the semaphore is
30 available the bidMsg will return and make you owner of the semaphore.
32 INPUTS
33 sigSem - pointer to semaphore structure
34 bidMsg - pointer to a struct SemaphoreMessage. This should lie in
35 public or at least shared memory.
37 RESULT
38 Principly none. Don't know. Just ignore it.
40 NOTES
41 Locks obtained with Procure() must be released with Vacate().
43 EXAMPLE
45 BUGS
47 SEE ALSO
48 Vacate()
50 INTERNALS
52 *****************************************************************************/
54 AROS_LIBFUNC_INIT
55 AROS_LIBBASE_EXT_DECL(struct ExecBase *,SysBase)
57 /* Prepare semaphore message to be a sent message */
58 bidMsg->ssm_Message.mn_Length=sizeof(struct SemaphoreMessage);
61 * If ln_Name field of message == 1, then this is a shared message, so
62 * we set the field to NULL. Otherwise, set it to the task requesting
63 * the semaphore. By the end, the ssm_Semaphore field contains the new
64 * owner of the semaphore.
66 if( (IPTR)(bidMsg->ssm_Message.mn_Node.ln_Name) == SM_SHARED )
67 bidMsg->ssm_Semaphore = NULL;
68 else
69 bidMsg->ssm_Semaphore = (struct SignalSemaphore *)FindTask(NULL);
71 /* Arbitrate for the semaphore structure - following like ObtainSema() */
72 Forbid();
74 sigSem->ss_QueueCount++;
76 Check if we own it
78 if( sigSem->ss_QueueCount == 0 )
80 /* No, and neither does anybody else - claim it as ours. */
81 sigSem->ss_Owner = (struct Task *)bidMsg->ssm_Semaphore;
82 sigSem->ss_NestCount++;
83 bidMsg->ssm_Semaphore = sigSem;
84 ReplyMsg((struct Message *)sigSem);
87 Otherwise check if we already own it
89 else if( sigSem->ss_Owner == (struct Task *)bidMsg->ssm_Semaphore )
91 /* Yes we do... */
92 sigSem->ss_NestCount++;
93 bidMsg->ssm_Semaphore = sigSem;
94 ReplyMsg((struct Message *)sigSem);
98 It is owned by somebody else, set up the waiter
100 else
102 struct SemaphoreRequest *sr;
104 * Unholy Hack v1.
106 * Whoever came up with this obviously has a twisted mind. We
107 * pretend that the SemaphoreMessage is really a SemaphoreRequest.
108 * Now, the code in ReleaseSemaphore that deals with this checks
109 * (after clearing bit 0) whether the sr_Waiter field is NULL. If
110 * so then it is really a SemaphoreMessage and should be returned.
112 * Now the bad part about this is what we are doing. There are two
113 * cases, in the Amiga case (bincompat), we are overwriting the
114 * ln_Type, ln_Pri and (half the) ln_Name fields. In the other
115 * case we are overwriting the ln_Name field completely. Now, in
116 * either case this doesn't matter as they do not contain any
117 * useful information that we haven't already claimed.
119 * Thank goodness C is so type unsafe.
121 sr = (struct SemaphoreRequest *)bidMsg;
122 if (bidMsg->ssm_Semaphore != NULL)
123 sr->sr_Waiter = NULL;
124 else
125 sr->sr_Waiter = (APTR)SM_SHARED;
127 AddTail((struct List *)&sigSem->ss_WaitQueue, (struct Node *)bidMsg);
129 /* All done. */
130 Permit();
132 /* Huh? */
133 return 0;
134 AROS_LIBFUNC_EXIT
135 } /* Procure */