source: rtems/cpukit/score/src/corespinlockwait.c @ da42259

4.104.115
Last change on this file since da42259 was 34e64879, checked in by Joel Sherrill <joel.sherrill@…>, on 06/11/09 at 15:18:08

2009-06-11 Joel Sherrill <joel.sherrill@…>

  • score/src/corespinlockwait.c: Mark timeout code which is not currently exercised by any API with the FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API conditional.
  • Property mode set to 100644
File size: 3.4 KB
Line 
1/*
2 *  SuperCore Spinlock Handler -- Wait for Spinlock
3 *
4 *  COPYRIGHT (c) 1989-2009.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems/system.h>
19#include <rtems/score/corespinlock.h>
20#include <rtems/score/states.h>
21#include <rtems/score/thread.h>
22#include <rtems/score/watchdog.h>
23
24/*PAGE
25 *
26 *  _CORE_spinlock_Wait
27 *
28 *  This function waits for the spinlock to become available.  Optionally,
29 *  a limit may be placed on the duration of the spin. 
30 *
31 *  Input parameters:
32 *    the_spinlock - the spinlock control block to initialize
33 *    wait         - true if willing to wait
34 *    timeout      - the maximum number of ticks to spin (0 is forever)
35 *
36 *  Output parameters:  NONE
37 */
38
39CORE_spinlock_Status _CORE_spinlock_Wait(
40  CORE_spinlock_Control  *the_spinlock,
41  bool                    wait,
42  Watchdog_Interval       timeout
43)
44{
45  ISR_Level level;
46  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
47    Watchdog_Interval       limit = _Watchdog_Ticks_since_boot + timeout;
48  #endif
49
50  _ISR_Disable( level );
51    if ( (the_spinlock->lock == CORE_SPINLOCK_LOCKED) &&
52         (the_spinlock->holder == _Thread_Executing->Object.id) ) {
53      _ISR_Enable( level );
54      return CORE_SPINLOCK_HOLDER_RELOCKING;
55    }
56    the_spinlock->users += 1;
57    for ( ;; ) {
58      if ( the_spinlock->lock == CORE_SPINLOCK_UNLOCKED ) {
59        the_spinlock->lock = CORE_SPINLOCK_LOCKED;
60        the_spinlock->holder = _Thread_Executing->Object.id;
61        _ISR_Enable( level );
62        return CORE_SPINLOCK_SUCCESSFUL;
63      }
64
65      /*
66       *  Spinlock is unavailable.  If not willing to wait, return.
67       */
68      if ( !wait ) {
69        the_spinlock->users -= 1;
70        _ISR_Enable( level );
71        return CORE_SPINLOCK_UNAVAILABLE;
72      }
73
74      #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
75        /*
76         *  They are willing to wait but there could be a timeout.
77         */
78        if ( timeout && (limit <= _Watchdog_Ticks_since_boot) ) {
79          the_spinlock->users -= 1;
80          _ISR_Enable( level );
81          return CORE_SPINLOCK_TIMEOUT;
82        }
83      #endif
84
85      /*
86       *  The thread is willing to spin so let's set things up so
87       *  another thread has a chance of running.  This spinlock has
88       *  to be released by either another thread or an ISR.  Since
89       *  POSIX does not say anything about ISRs, that implies that
90       *  another thread must be able to run while spinning.  We are
91       *  not blocking so that implies we are at least preemptible
92       *  and possibly time-sliced. 
93       * 
94       *  So first, we will enable interrpts to allow for them to happen.
95       *  Then we will "flash" the thread dispatching critical section
96       *  so other threads have a chance to run.
97       *
98       *  A spinlock cannot be deleted while it is being used so we are
99       *  safe from deletion.
100       */
101
102       _ISR_Enable( level );
103       /* An ISR could occur here */
104
105       _Thread_Enable_dispatch();
106       /* Another thread could get dispatched here */
107       
108       /* Reenter the critical sections so we can attempt the lock again. */
109       _Thread_Disable_dispatch();
110
111       _ISR_Disable( level );
112    }
113
114}
Note: See TracBrowser for help on using the repository browser.