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

4.104.114.84.95
Last change on this file since 3e30f27 was 9af31a6, checked in by Joel Sherrill <joel.sherrill@…>, on 11/09/99 at 02:32:37

Moved include files to hppa1.1 subdirectory and put their sources
in the include directory.

  • 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 <hppa1.1/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.