source: rtems/c/src/exec/score/src/coremutexsurrender.c @ 6f1118a

Last change on this file since 6f1118a was 6f1118a, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 30, 2001 at 6:32:12 PM

2001-08-30 Joel Sherrill <joel@…>

  • src/coremutex.c, src/coremutexseize.c, src/coremutexsurrender.c: The per thread field resource_count should only be manipulated when a mutex is priority ceiling or priority inherit. This was reported by Chris Johns <ccj@…> who also noticed that the use of switches for all disciplines generated less efficient code than using explicit tests for the one or two cases we were really interested in. Further review of his modifications made it apparent that the "isa" methods to test mutex discipline were not being used so this modification was swept into the code as well.
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 *  Mutex Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the Mutex Handler.
7 *  This handler provides synchronization and mutual exclusion capabilities.
8 *
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
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/system.h>
20#include <rtems/score/isr.h>
21#include <rtems/score/coremutex.h>
22#include <rtems/score/states.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/threadq.h>
25
26/*
27 *  _CORE_mutex_Surrender
28 *
29 *  DESCRIPTION:
30 *
31 *  This routine frees a unit to the mutex.  If a task was blocked waiting for
32 *  a unit from this mutex, then that task will be readied and the unit
33 *  given to that task.  Otherwise, the unit will be returned to the mutex.
34 *
35 *  Input parameters:
36 *    the_mutex            - the mutex to be flushed
37 *    id                   - id of parent mutex
38 *    api_mutex_mp_support - api dependent MP support actions
39 *
40 *  Output parameters:
41 *    CORE_MUTEX_STATUS_SUCCESSFUL - if successful
42 *    core error code              - if unsuccessful
43 */
44
45CORE_mutex_Status _CORE_mutex_Surrender(
46  CORE_mutex_Control                *the_mutex,
47  Objects_Id                         id,
48  CORE_mutex_API_mp_support_callout  api_mutex_mp_support
49)
50{
51  Thread_Control *the_thread;
52  Thread_Control *holder;
53
54  holder    = the_mutex->holder;
55
56  /*
57   *  The following code allows a thread (or ISR) other than the thread
58   *  which acquired the mutex to release that mutex.  This is only
59   *  allowed when the mutex in quetion is FIFO or simple Priority
60   *  discipline.  But Priority Ceiling or Priority Inheritance mutexes
61   *  must be released by the thread which acquired them.
62   */ 
63
64  if ( the_mutex->Attributes.only_owner_release ) {
65    if ( !_Thread_Is_executing( holder ) )
66      return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
67  }
68
69  /* XXX already unlocked -- not right status */
70
71  if ( !the_mutex->nest_count ) 
72    return( CORE_MUTEX_STATUS_SUCCESSFUL );
73
74  the_mutex->nest_count--;
75
76  if ( the_mutex->nest_count != 0 ) {
77    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
78      case CORE_MUTEX_NESTING_ACQUIRES:
79        return CORE_MUTEX_STATUS_SUCCESSFUL;
80      case CORE_MUTEX_NESTING_IS_ERROR:
81        /* should never occur */
82        return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
83      case CORE_MUTEX_NESTING_BLOCKS:
84        /* Currently no API exercises this behavior. */
85        break;
86    }
87  }
88
89  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
90       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
91    holder->resource_count--;
92  the_mutex->holder    = NULL;
93  the_mutex->holder_id = 0;
94
95  /*
96   *  Whether or not someone is waiting for the mutex, an
97   *  inherited priority must be lowered if this is the last
98   *  mutex (i.e. resource) this task has.
99   */
100
101  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
102       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
103    if ( holder->resource_count == 0 && 
104         holder->real_priority != holder->current_priority ) {
105       _Thread_Change_priority( holder, holder->real_priority, TRUE );
106    }
107  }
108
109  if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) {
110
111#if defined(RTEMS_MULTIPROCESSING)
112    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
113     
114      the_mutex->holder     = NULL;
115      the_mutex->holder_id  = the_thread->Object.id;
116      the_mutex->nest_count = 1;
117
118      ( *api_mutex_mp_support)( the_thread, id );
119
120    } else 
121#endif
122    {
123
124      the_mutex->holder     = the_thread;
125      the_mutex->holder_id  = the_thread->Object.id;
126      the_thread->resource_count++;
127      the_mutex->nest_count = 1;
128
129     /*
130      *  No special action for priority inheritance or priority ceiling
131      *  because the_thread is guaranteed to be the highest priority
132      *  thread waiting for the mutex.
133      */
134    }
135  } else
136    the_mutex->lock = CORE_MUTEX_UNLOCKED;
137
138  return( CORE_MUTEX_STATUS_SUCCESSFUL );
139}
140
Note: See TracBrowser for help on using the repository browser.