source: rtems/cpukit/score/src/coremutexsurrender.c @ fa6b0f5

4.104.114.84.95
Last change on this file since fa6b0f5 was a8eed23, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/27/05 at 05:57:05

Include config.h.

  • Property mode set to 100644
File size: 4.2 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.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <rtems/system.h>
24#include <rtems/score/isr.h>
25#include <rtems/score/coremutex.h>
26#include <rtems/score/states.h>
27#include <rtems/score/thread.h>
28#include <rtems/score/threadq.h>
29
30/*
31 *  _CORE_mutex_Surrender
32 *
33 *  DESCRIPTION:
34 *
35 *  This routine frees a unit to the mutex.  If a task was blocked waiting for
36 *  a unit from this mutex, then that task will be readied and the unit
37 *  given to that task.  Otherwise, the unit will be returned to the mutex.
38 *
39 *  Input parameters:
40 *    the_mutex            - the mutex to be flushed
41 *    id                   - id of parent mutex
42 *    api_mutex_mp_support - api dependent MP support actions
43 *
44 *  Output parameters:
45 *    CORE_MUTEX_STATUS_SUCCESSFUL - if successful
46 *    core error code              - if unsuccessful
47 */
48
49CORE_mutex_Status _CORE_mutex_Surrender(
50  CORE_mutex_Control                *the_mutex,
51  Objects_Id                         id,
52  CORE_mutex_API_mp_support_callout  api_mutex_mp_support
53)
54{
55  Thread_Control *the_thread;
56  Thread_Control *holder;
57
58  holder    = the_mutex->holder;
59
60  /*
61   *  The following code allows a thread (or ISR) other than the thread
62   *  which acquired the mutex to release that mutex.  This is only
63   *  allowed when the mutex in quetion is FIFO or simple Priority
64   *  discipline.  But Priority Ceiling or Priority Inheritance mutexes
65   *  must be released by the thread which acquired them.
66   */
67
68  if ( the_mutex->Attributes.only_owner_release ) {
69    if ( !_Thread_Is_executing( holder ) )
70      return CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE;
71  }
72
73  /* XXX already unlocked -- not right status */
74
75  if ( !the_mutex->nest_count )
76    return CORE_MUTEX_STATUS_SUCCESSFUL;
77
78  the_mutex->nest_count--;
79
80  if ( the_mutex->nest_count != 0 ) {
81    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
82      case CORE_MUTEX_NESTING_ACQUIRES:
83        return CORE_MUTEX_STATUS_SUCCESSFUL;
84      case CORE_MUTEX_NESTING_IS_ERROR:
85        /* should never occur */
86        return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
87      case CORE_MUTEX_NESTING_BLOCKS:
88        /* Currently no API exercises this behavior. */
89        break;
90    }
91  }
92
93  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
94       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
95    holder->resource_count--;
96  the_mutex->holder    = NULL;
97  the_mutex->holder_id = 0;
98
99  /*
100   *  Whether or not someone is waiting for the mutex, an
101   *  inherited priority must be lowered if this is the last
102   *  mutex (i.e. resource) this task has.
103   */
104
105  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
106       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
107    if ( holder->resource_count == 0 &&
108         holder->real_priority != holder->current_priority ) {
109      _Thread_Change_priority( holder, holder->real_priority, TRUE );
110    }
111  }
112
113  if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) {
114
115#if defined(RTEMS_MULTIPROCESSING)
116    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
117
118      the_mutex->holder     = NULL;
119      the_mutex->holder_id  = the_thread->Object.id;
120      the_mutex->nest_count = 1;
121
122      ( *api_mutex_mp_support)( the_thread, id );
123
124    } else
125#endif
126    {
127
128      the_mutex->holder     = the_thread;
129      the_mutex->holder_id  = the_thread->Object.id;
130      if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
131           _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
132        the_thread->resource_count++;
133      the_mutex->nest_count = 1;
134
135     /*
136      *  No special action for priority inheritance or priority ceiling
137      *  because the_thread is guaranteed to be the highest priority
138      *  thread waiting for the mutex.
139      */
140    }
141  } else
142    the_mutex->lock = CORE_MUTEX_UNLOCKED;
143
144  return CORE_MUTEX_STATUS_SUCCESSFUL;
145}
Note: See TracBrowser for help on using the repository browser.