source: rtems/cpukit/posix/src/pthread.c @ e97806a

5
Last change on this file since e97806a was e97806a, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 14, 2018 at 5:20:05 PM

posix: Split posix_api_configuration_table

Use separate configuration variables to avoid false dependencies.

Update #2514.

  • Property mode set to 100644
File size: 5.3 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_ticks( &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
126  api = created->API_Extensions[ THREAD_API_POSIX ];
127
128  api->Sporadic.thread = created;
129  _Watchdog_Preinitialize( &api->Sporadic.Timer, _Per_CPU_Get_by_index( 0 ) );
130  _Watchdog_Initialize( &api->Sporadic.Timer, _POSIX_Threads_Sporadic_timer );
131  _Priority_Node_set_inactive( &api->Sporadic.Low_priority );
132
133  return true;
134}
135
136static void _POSIX_Threads_Terminate_extension( Thread_Control *executing )
137{
138  POSIX_API_Control *api;
139  ISR_lock_Context   lock_context;
140
141  api = executing->API_Extensions[ THREAD_API_POSIX ];
142
143  _Thread_State_acquire( executing, &lock_context );
144  _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
145  _Thread_State_release( executing, &lock_context );
146}
147
148/*
149 *  _POSIX_Threads_Exitted_extension
150 *
151 *  This method is invoked each time a thread exits.
152 */
153static void _POSIX_Threads_Exitted_extension(
154  Thread_Control *executing
155)
156{
157  /*
158   *  If the executing thread was not created with the POSIX API, then this
159   *  API do not get to define its exit behavior.
160   */
161  if ( _Objects_Get_API( executing->Object.id ) == OBJECTS_POSIX_API )
162    pthread_exit( executing->Wait.return_argument );
163}
164
165User_extensions_Control _POSIX_Threads_User_extensions = {
166  .Callouts = {
167    .thread_create    = _POSIX_Threads_Create_extension,
168    .thread_exitted   = _POSIX_Threads_Exitted_extension,
169    .thread_terminate = _POSIX_Threads_Terminate_extension
170  }
171};
172
173/*
174 *  _POSIX_Threads_Manager_initialization
175 *
176 *  This routine initializes all threads manager related data structures.
177 */
178static void _POSIX_Threads_Manager_initialization(void)
179{
180  _Thread_Initialize_information(
181    &_POSIX_Threads_Information, /* object information table */
182    OBJECTS_POSIX_API,           /* object API */
183    OBJECTS_POSIX_THREADS,       /* object class */
184    _Configuration_POSIX_Maximum_threads
185  );
186
187  /*
188   *  Add all the extensions for this API
189   */
190  _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions );
191
192  /*
193   *  If we supported MP, then here we would ...
194   *       Register the MP Process Packet routine.
195   */
196}
197
198RTEMS_SYSINIT_ITEM(
199  _POSIX_Threads_Manager_initialization,
200  RTEMS_SYSINIT_POSIX_THREADS,
201  RTEMS_SYSINIT_ORDER_MIDDLE
202);
Note: See TracBrowser for help on using the repository browser.