source: rtems/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.c @ bb11d7e

4.104.114.84.95
Last change on this file since bb11d7e was f817b02, checked in by Joel Sherrill <joel.sherrill@…>, on 11/04/99 at 18:05:09

The files in libcpu should not be directly dependent on any BSP. In
particular, using bsp.h, or getting information from the BSP which
should properly be obtained from RTEMS is forbidden. This is
necessary to strengthen the division between the BSP independent
parts of RTEMS and the BSPs themselves. This started after
comments and analysis by Ralf Corsepius <corsepiu@…>.
The changes primarily eliminated the need to include bsp.h and
peeking at BSP_Configuration. The use of Cpu_table in each
BSP needs to be eliminated.

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 *  Description:
3 *      HPPA fast spinlock semaphores based on LDCWX instruction.
4 *      These semaphores are not known to RTEMS.
5 *
6 *  TODO:
7 *      Put node number in high 16 bits of flag??
8 *      XXX: Need h_s_deallocate
9 *
10 *  COPYRIGHT (c) 1994 by Division Incorporated
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.OARcorp.com/rtems/license.html.
15 *
16 *  $Id$
17 */
18
19#include <rtems.h>
20
21#include "semaphore.h"
22
23/*
24 * Report fatal semaphore error
25 */
26
27#define SEM_FATAL_ERROR(sp)  rtems_fatal_error_occurred((rtems_unsigned32) sp)
28
29#define SEM_CHECK(sp)   do { \
30                              if (((sp) == 0) || (int) (sp) & 0xf) \
31                              { \
32                                  SEM_FATAL_ERROR(sp); \
33                              } \
34                         } while (0)
35
36/*
37 * Init a semaphore to be free
38 */
39
40#define SEM_FREE_INIT(sp) \
41    do { \
42        (sp)->lock = 1; \
43        (sp)->flags = 0; \
44        (sp)->owner_tcb  = 0; \
45    } while (0)
46
47/*
48 * Grab a semaphore recording its owner.
49 */
50
51#define SEM_MARK_GRABBED(sp) \
52    do { \
53        (sp)->owner_tcb  = _Thread_Executing; \
54    } while (0)
55
56/*
57 * Mark the semaphore busy
58 */
59
60#define SEM_MARK_BUSY(sp)    ((sp)->flags |= HPPA_SEM_IN_USE)
61
62/*
63 * Is a semaphore available?
64 */
65
66#define SEM_IS_AVAILABLE(sp)  ((sp)->owner_tcb == 0)
67
68/*
69 * The pool control semaphore is the first in the pool
70 */
71
72#define SEM_CONTROL  (&hppa_semaphore_pool[0])
73#define SEM_FIRST    (&hppa_semaphore_pool[1])
74
75#define SEM_PRIVATE(cookie)  rtems_interrupt_disable(cookie)
76
77#define SEM_PUBLIC(cookie)   rtems_interrupt_enable(cookie)
78
79
80/*
81 * Control variables for the pool
82 */
83
84hppa_semaphore_t *hppa_semaphore_pool;        /* ptr to first */
85int               hppa_semaphores;
86int               hppa_semaphores_available;
87
88void
89hppa_semaphore_pool_initialize(void *pool_base,
90                               int   pool_size)
91{
92    hppa_semaphore_t *sp;
93    int align_factor;
94    rtems_unsigned32 isr_level;
95
96    /*
97     * round pool_base up to be a multiple of SEM_ALIGN
98     */
99
100    align_factor = SEM_ALIGN - (((int) pool_base) & (SEM_ALIGN-1));
101    if (align_factor != SEM_ALIGN)
102    {
103        pool_base += align_factor;
104        pool_size -= align_factor;
105    }
106
107    /*
108     * How many can the pool hold?
109     * Assumes the semaphores are SEM_ALIGN bytes each
110     */
111
112    if (sizeof(hppa_semaphore_t) != SEM_ALIGN)
113        rtems_fatal_error_occurred(RTEMS_INVALID_SIZE);
114
115    pool_size &= ~(SEM_ALIGN - 1);
116
117    SEM_PRIVATE(isr_level);
118
119    hppa_semaphore_pool = pool_base;
120    hppa_semaphores = pool_size / SEM_ALIGN;
121
122    /*
123     * If we are node0, then init all in the pool
124     */
125
126#if 0
127    if (cpu_number == 0)
128#else
129    if (_Configuration_Table->User_multiprocessing_table->node == 1)
130#endif
131    {
132        /*
133         * Tell other cpus we are not done, jic
134         */
135        SEM_CONTROL->user = rtems_build_name('!', 'D', 'N', 'E');
136
137        for (sp=SEM_FIRST; sp < &hppa_semaphore_pool[hppa_semaphores]; sp++)
138            SEM_FREE_INIT(sp);
139        SEM_FREE_INIT(SEM_CONTROL);
140    }
141
142    /*
143     * Tell other cpus we are done, or wait for it to be done if on another cpu
144     */
145
146#if 0
147    if (cpu_number == 0)
148#else
149    if (_Configuration_Table->User_multiprocessing_table->node == 1)
150#endif
151        SEM_CONTROL->user = rtems_build_name('D', 'O', 'N', 'E');
152    else
153        while (SEM_CONTROL->user != rtems_build_name('D', 'O', 'N', 'E'))
154            ;
155
156    hppa_semaphores_available = hppa_semaphores;
157
158    SEM_PUBLIC(isr_level);
159}
160
161/*
162 *  Function:   hppa_semaphore_acquire
163 *  Created:    94/11/29
164 *  RespEngr:   tony bennett
165 *
166 *  Description:
167 *      Acquire a semaphore.   Will spin on the semaphore unless
168 *      'flag' says not to.
169 *
170 *  Parameters:
171 *
172 *
173 *  Returns:
174 *      0        -- if did not acquire
175 *      non-zero -- if acquired semaphore
176 *                      (actually this is the spin count)
177 *
178 *  Notes:
179 *      There is no requirement that the semaphore be within the pool
180 *
181 *  Deficiencies/ToDo:
182 *
183 */
184
185
186rtems_unsigned32
187hppa_semaphore_acquire(hppa_semaphore_t *sp,
188                       int               flag)
189{
190    rtems_unsigned32 lock_value;
191    rtems_unsigned32 spin_count = 1;
192
193    SEM_CHECK(sp);
194
195    for (;;)
196    {
197        HPPA_ASM_LDCWS(0, 0, sp, lock_value);
198
199        if (lock_value)         /* we now own the lock */
200        {
201            SEM_MARK_GRABBED(sp);
202            return spin_count ? spin_count : ~0;        /* jic */
203        }
204
205        if (flag & HPPA_SEM_NO_SPIN)
206            return 0;
207
208        spin_count++;
209    }
210}
211
212void
213hppa_semaphore_release(hppa_semaphore_t *sp)
214{
215    SEM_CHECK(sp);
216
217    if (sp->owner_tcb != _Thread_Executing)
218        SEM_FATAL_ERROR("owner mismatch");
219
220    sp->lock = 1;
221}
222
223
224/*
225 *  Function:   hppa_semaphore_allocate
226 *  Created:    94/11/29
227 *  RespEngr:   tony bennett
228 *
229 *  Description:
230 *      Get a pointer to a semaphore.
231 *
232 *  Parameters:
233 *      which -- if 0, then allocate a free semaphore from the pool
234 *               if non-zero, then return pointer to that one, even
235 *                  if it is already busy.
236 *
237 *  Returns:
238 *      successful -- pointer to semaphore
239 *                    NULL otherwise
240 *
241 *  Notes:
242 *
243 *
244 *  Deficiencies/ToDo:
245 *
246 *
247 */
248
249hppa_semaphore_t *
250hppa_semaphore_allocate(rtems_unsigned32 which,
251                        int              flag)
252{
253    hppa_semaphore_t *sp = 0;
254
255    /*
256     * grab the control semaphore
257     */
258
259    if (hppa_semaphore_acquire(SEM_CONTROL, 0) == 0)
260        SEM_FATAL_ERROR("could not grab control semaphore");
261
262    /*
263     * Find a free one and init it
264     */
265
266    if (which)
267    {
268        if (which >= hppa_semaphores)
269            SEM_FATAL_ERROR("requested non-existent semaphore");
270        sp = &hppa_semaphore_pool[which];
271
272        /*
273         * if it is "free", then mark it claimed now.
274         * If it is not free then we are done.
275         */
276
277        if (SEM_IS_AVAILABLE(sp))
278            goto allmine;
279    }
280    else for (sp = SEM_FIRST;
281              sp < &hppa_semaphore_pool[hppa_semaphores];
282              sp++)
283    {
284        if (SEM_IS_AVAILABLE(sp))
285        {
286allmine:    SEM_FREE_INIT(sp);
287            SEM_MARK_BUSY(sp);
288            if ( ! (flag & HPPA_SEM_INITIALLY_FREE))
289                SEM_MARK_GRABBED(sp);
290            break;
291        }
292    }
293
294    /*
295     * Free up the control semaphore
296     */
297
298    hppa_semaphore_release(SEM_CONTROL);
299
300    return sp;
301}
302
Note: See TracBrowser for help on using the repository browser.