source: rtems/cpukit/posix/src/pthread.c @ 0e16fa45

5
Last change on this file since 0e16fa45 was 54f35888, checked in by Sebastian Huber <sebastian.huber@…>, on 10/25/18 at 08:54:12

posix: Provide threads by default

Update #2514.

  • Property mode set to 100644
File size: 5.4 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#if defined(RTEMS_POSIX_API)
38#include <rtems/posix/psignalimpl.h>
39#endif
40#include <rtems/posix/config.h>
41#include <rtems/posix/keyimpl.h>
42#include <rtems/score/assert.h>
43#include <rtems/score/schedulerimpl.h>
44
45Thread_Information _POSIX_Threads_Information;
46
47#if defined(RTEMS_POSIX_API)
48void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog )
49{
50  POSIX_API_Control    *api;
51  Thread_Control       *the_thread;
52  Thread_queue_Context  queue_context;
53
54  api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic.Timer );
55  the_thread = api->Sporadic.thread;
56
57  _Thread_queue_Context_initialize( &queue_context );
58  _Thread_queue_Context_clear_priority_updates( &queue_context );
59  _Thread_Wait_acquire( the_thread, &queue_context );
60
61  if ( _Priority_Node_is_active( &api->Sporadic.Low_priority ) ) {
62    _Thread_Priority_add(
63      the_thread,
64      &the_thread->Real_priority,
65      &queue_context
66    );
67    _Thread_Priority_remove(
68      the_thread,
69      &api->Sporadic.Low_priority,
70      &queue_context
71    );
72    _Priority_Node_set_inactive( &api->Sporadic.Low_priority );
73  }
74
75  _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
76  _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
77
78  _Thread_Wait_release( the_thread, &queue_context );
79  _Thread_Priority_update( &queue_context );
80}
81
82void _POSIX_Threads_Sporadic_budget_callout( Thread_Control *the_thread )
83{
84  POSIX_API_Control    *api;
85  Thread_queue_Context  queue_context;
86
87  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
88
89  _Thread_queue_Context_initialize( &queue_context );
90  _Thread_queue_Context_clear_priority_updates( &queue_context );
91  _Thread_Wait_acquire( the_thread, &queue_context );
92
93  /*
94   *  This will prevent the thread from consuming its entire "budget"
95   *  while at low priority.
96   */
97  the_thread->cpu_time_budget = UINT32_MAX;
98
99  if ( !_Priority_Node_is_active( &api->Sporadic.Low_priority ) ) {
100    _Thread_Priority_add(
101      the_thread,
102      &api->Sporadic.Low_priority,
103      &queue_context
104    );
105    _Thread_Priority_remove(
106      the_thread,
107      &the_thread->Real_priority,
108      &queue_context
109    );
110  }
111
112  _Thread_Wait_release( the_thread, &queue_context );
113  _Thread_Priority_update( &queue_context );
114}
115
116/*
117 *  _POSIX_Threads_Create_extension
118 *
119 *  This method is invoked for each thread created.
120 */
121
122static bool _POSIX_Threads_Create_extension(
123  Thread_Control *executing RTEMS_UNUSED,
124  Thread_Control *created
125)
126{
127  POSIX_API_Control *api;
128
129  api = created->API_Extensions[ THREAD_API_POSIX ];
130
131  api->Sporadic.thread = created;
132  _Watchdog_Preinitialize( &api->Sporadic.Timer, _Per_CPU_Get_by_index( 0 ) );
133  _Watchdog_Initialize( &api->Sporadic.Timer, _POSIX_Threads_Sporadic_timer );
134  _Priority_Node_set_inactive( &api->Sporadic.Low_priority );
135
136  return true;
137}
138
139static void _POSIX_Threads_Terminate_extension( Thread_Control *executing )
140{
141  POSIX_API_Control *api;
142  ISR_lock_Context   lock_context;
143
144  api = executing->API_Extensions[ THREAD_API_POSIX ];
145
146  _Thread_State_acquire( executing, &lock_context );
147  _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer );
148  _Thread_State_release( executing, &lock_context );
149}
150#endif
151
152/*
153 *  _POSIX_Threads_Exitted_extension
154 *
155 *  This method is invoked each time a thread exits.
156 */
157static void _POSIX_Threads_Exitted_extension(
158  Thread_Control *executing
159)
160{
161  /*
162   *  If the executing thread was not created with the POSIX API, then this
163   *  API do not get to define its exit behavior.
164   */
165  if ( _Objects_Get_API( executing->Object.id ) == OBJECTS_POSIX_API )
166    pthread_exit( executing->Wait.return_argument );
167}
168
169User_extensions_Control _POSIX_Threads_User_extensions = {
170  .Callouts = {
171#if defined(RTEMS_POSIX_API)
172    .thread_create    = _POSIX_Threads_Create_extension,
173    .thread_terminate = _POSIX_Threads_Terminate_extension,
174#endif
175    .thread_exitted   = _POSIX_Threads_Exitted_extension
176  }
177};
178
179/*
180 *  _POSIX_Threads_Manager_initialization
181 *
182 *  This routine initializes all threads manager related data structures.
183 */
184static void _POSIX_Threads_Manager_initialization(void)
185{
186  _Thread_Initialize_information(
187    &_POSIX_Threads_Information, /* object information table */
188    OBJECTS_POSIX_API,           /* object API */
189    OBJECTS_POSIX_THREADS,       /* object class */
190    _Configuration_POSIX_Maximum_threads
191  );
192
193  /*
194   *  Add all the extensions for this API
195   */
196  _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions );
197
198  /*
199   *  If we supported MP, then here we would ...
200   *       Register the MP Process Packet routine.
201   */
202}
203
204RTEMS_SYSINIT_ITEM(
205  _POSIX_Threads_Manager_initialization,
206  RTEMS_SYSINIT_POSIX_THREADS,
207  RTEMS_SYSINIT_ORDER_MIDDLE
208);
Note: See TracBrowser for help on using the repository browser.