source: rtems/cpukit/posix/src/pthread.c @ 3f3f4248

5
Last change on this file since 3f3f4248 was 3f3f4248, checked in by Sebastian Huber <sebastian.huber@…>, on 10/17/17 at 07:20:20

posix: Remove POSIX_API_Control::schedparam

Move sporadic server scheduler parameters to
POSIX_API_Control::Sporadic. Remove redundant scheduler priority
parameter.

Update #2514.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/**
2 * @file
3 *
4 * @brief Private Support Information for POSIX Threads
5 * @ingroup POSIX_PTHREADS Private Threads
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2014.
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.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20#include <stdio.h>
21
22#include <errno.h>
23#include <pthread.h>
24#include <limits.h>
25#include <assert.h>
26
27#include <rtems/system.h>
28#include <rtems/config.h>
29#include <rtems/sysinit.h>
30#include <rtems/score/stack.h>
31#include <rtems/score/threadimpl.h>
32#include <rtems/score/threadqimpl.h>
33#include <rtems/score/userextimpl.h>
34#include <rtems/score/wkspace.h>
35#include <rtems/posix/pthreadimpl.h>
36#include <rtems/posix/priorityimpl.h>
37#include <rtems/posix/psignalimpl.h>
38#include <rtems/posix/config.h>
39#include <rtems/posix/keyimpl.h>
40#include <rtems/score/assert.h>
41#include <rtems/score/schedulerimpl.h>
42
43Thread_Information _POSIX_Threads_Information;
44
45void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog )
46{
47  POSIX_API_Control    *api;
48  Thread_Control       *the_thread;
49  Thread_queue_Context  queue_context;
50
51  api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic.Timer );
52  the_thread = api->Sporadic.thread;
53
54  _Thread_queue_Context_initialize( &queue_context );
55  _Thread_queue_Context_clear_priority_updates( &queue_context );
56  _Thread_Wait_acquire( the_thread, &queue_context );
57
58  if ( _Priority_Node_is_active( &api->Sporadic.Low_priority ) ) {
59    _Thread_Priority_add(
60      the_thread,
61      &the_thread->Real_priority,
62      &queue_context
63    );
64    _Thread_Priority_remove(
65      the_thread,
66      &api->Sporadic.Low_priority,
67      &queue_context
68    );
69    _Priority_Node_set_inactive( &api->Sporadic.Low_priority );
70  }
71
72  _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer );
73  _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
74
75  _Thread_Wait_release( the_thread, &queue_context );
76  _Thread_Priority_update( &queue_context );
77}
78
79void _POSIX_Threads_Sporadic_budget_callout( Thread_Control *the_thread )
80{
81  POSIX_API_Control    *api;
82  Thread_queue_Context  queue_context;
83
84  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
85
86  _Thread_queue_Context_initialize( &queue_context );
87  _Thread_queue_Context_clear_priority_updates( &queue_context );
88  _Thread_Wait_acquire( the_thread, &queue_context );
89
90  /*
91   *  This will prevent the thread from consuming its entire "budget"
92   *  while at low priority.
93   */
94  the_thread->cpu_time_budget = UINT32_MAX;
95
96  if ( !_Priority_Node_is_active( &api->Sporadic.Low_priority ) ) {
97    _Thread_Priority_add(
98      the_thread,
99      &api->Sporadic.Low_priority,
100      &queue_context
101    );
102    _Thread_Priority_remove(
103      the_thread,
104      &the_thread->Real_priority,
105      &queue_context
106    );
107  }
108
109  _Thread_Wait_release( the_thread, &queue_context );
110  _Thread_Priority_update( &queue_context );
111}
112
113/*
114 *  _POSIX_Threads_Create_extension
115 *
116 *  This method is invoked for each thread created.
117 */
118
119static bool _POSIX_Threads_Create_extension(
120  Thread_Control *executing RTEMS_UNUSED,
121  Thread_Control *created
122)
123{
124  POSIX_API_Control *api;
125  POSIX_API_Control *executing_api;
126
127  api = created->API_Extensions[ THREAD_API_POSIX ];
128
129  /*
130   *  If the thread is not a posix thread, then all posix signals are blocked
131   *  by default.
132   *
133   *  The check for class == 1 is debug.  Should never really happen.
134   */
135  RTEMS_STATIC_ASSERT( SIGNAL_EMPTY_MASK == 0, signals_pending );
136  if ( _Objects_Get_API( created->Object.id ) == OBJECTS_POSIX_API
137       #if defined(RTEMS_DEBUG)
138         && _Objects_Get_class( created->Object.id ) == 1
139       #endif
140  ) {
141    executing_api = _Thread_Get_executing()->API_Extensions[ THREAD_API_POSIX ];
142    api->signals_unblocked = executing_api->signals_unblocked;
143  }
144
145  api->Sporadic.thread = created;
146  _Watchdog_Preinitialize( &api->Sporadic.Timer, _Per_CPU_Get_by_index( 0 ) );
147  _Watchdog_Initialize( &api->Sporadic.Timer, _POSIX_Threads_Sporadic_timer );
148  _Priority_Node_set_inactive( &api->Sporadic.Low_priority );
149
150  return true;
151}
152
153static void _POSIX_Threads_Terminate_extension( Thread_Control *executing )
154{
155  POSIX_API_Control *api;
156  ISR_lock_Context   lock_context;
157
158  api = executing->API_Extensions[ THREAD_API_POSIX ];
159
160  _Thread_State_acquire( executing, &lock_context );
161
162  if ( api->schedpolicy == SCHED_SPORADIC ) {
163    _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer );
164  }
165
166  _Thread_State_release( executing, &lock_context );
167}
168
169/*
170 *  _POSIX_Threads_Exitted_extension
171 *
172 *  This method is invoked each time a thread exits.
173 */
174static void _POSIX_Threads_Exitted_extension(
175  Thread_Control *executing
176)
177{
178  /*
179   *  If the executing thread was not created with the POSIX API, then this
180   *  API do not get to define its exit behavior.
181   */
182  if ( _Objects_Get_API( executing->Object.id ) == OBJECTS_POSIX_API )
183    pthread_exit( executing->Wait.return_argument );
184}
185
186User_extensions_Control _POSIX_Threads_User_extensions = {
187  .Callouts = {
188    .thread_create    = _POSIX_Threads_Create_extension,
189    .thread_exitted   = _POSIX_Threads_Exitted_extension,
190    .thread_terminate = _POSIX_Threads_Terminate_extension
191  }
192};
193
194/*
195 *  _POSIX_Threads_Manager_initialization
196 *
197 *  This routine initializes all threads manager related data structures.
198 */
199static void _POSIX_Threads_Manager_initialization(void)
200{
201  _Thread_Initialize_information(
202    &_POSIX_Threads_Information, /* object information table */
203    OBJECTS_POSIX_API,           /* object API */
204    OBJECTS_POSIX_THREADS,       /* object class */
205    Configuration_POSIX_API.maximum_threads,
206                                 /* maximum objects of this class */
207    true,                        /* true if names for this object are strings */
208    _POSIX_PATH_MAX              /* maximum length of each object's name */
209  );
210
211  /*
212   *  Add all the extensions for this API
213   */
214  _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions );
215
216  /*
217   *  If we supported MP, then here we would ...
218   *       Register the MP Process Packet routine.
219   */
220}
221
222RTEMS_SYSINIT_ITEM(
223  _POSIX_Threads_Manager_initialization,
224  RTEMS_SYSINIT_POSIX_THREADS,
225  RTEMS_SYSINIT_ORDER_MIDDLE
226);
Note: See TracBrowser for help on using the repository browser.