source: rtems/cpukit/posix/src/pthreadsetschedparam.c @ 127c20eb

5
Last change on this file since 127c20eb was 1a4eac50, checked in by Sebastian Huber <sebastian.huber@…>, on 06/15/16 at 14:31:33

posix: Generalize _POSIX_Priority_To_core()

Move POSIX API priority validation into _POSIX_Priority_To_core().

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/**
2 * @file
3 *
4 * @brief Function sets scheduling policy and parameters of the thread
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  13.5.2 Dynamic Thread Scheduling Parameters Access,
10 *         P1003.1c/Draft 10, p. 124
11 */
12
13/*  COPYRIGHT (c) 1989-2014.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21#if HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <pthread.h>
26#include <errno.h>
27
28#include <rtems/posix/pthreadimpl.h>
29#include <rtems/posix/priorityimpl.h>
30#include <rtems/score/threadimpl.h>
31#include <rtems/score/schedulerimpl.h>
32
33typedef struct {
34  int                                  policy;
35  const struct sched_param            *param;
36  Thread_CPU_budget_algorithms         budget_algorithm;
37  Thread_CPU_budget_algorithm_callout  budget_callout;
38  int                                  error;
39} POSIX_Set_sched_param_context;
40
41static bool _POSIX_Set_sched_param_filter(
42  Thread_Control   *the_thread,
43  Priority_Control *new_priority_p,
44  void             *arg
45)
46{
47  POSIX_Set_sched_param_context *context;
48  const struct sched_param      *param;
49  const Scheduler_Control       *scheduler;
50  POSIX_API_Control             *api;
51  int                            low_prio;
52  int                            high_prio;
53  bool                           valid;
54  Priority_Control               core_low_prio;
55  Priority_Control               core_high_prio;
56  Priority_Control               current_priority;
57
58  context = arg;
59  param = context->param;
60  scheduler = _Scheduler_Get_own( the_thread );
61
62  if ( context->policy == SCHED_SPORADIC ) {
63    low_prio = param->sched_ss_low_priority;
64    high_prio = param->sched_priority;
65  } else {
66    low_prio = param->sched_priority;
67    high_prio = low_prio;
68  }
69
70  core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid );
71  if ( !valid ) {
72    context->error = EINVAL;
73    return false;
74  }
75
76  core_high_prio = _POSIX_Priority_To_core( scheduler, high_prio, &valid );
77  if ( !valid ) {
78    context->error = EINVAL;
79    return false;
80  }
81
82  *new_priority_p = core_high_prio;
83
84  current_priority = the_thread->current_priority;
85  the_thread->real_priority = core_high_prio;
86
87  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
88
89  _Watchdog_Per_CPU_remove_relative( &api->Sporadic.Timer );
90
91  api->Attributes.schedpolicy = context->policy;
92  api->Attributes.schedparam  = *param;
93  api->Sporadic.low_priority  = core_low_prio;
94  api->Sporadic.high_priority = core_high_prio;
95
96  the_thread->budget_algorithm = context->budget_algorithm;
97  the_thread->budget_callout   = context->budget_callout;
98
99  if ( context->policy == SCHED_SPORADIC ) {
100    _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
101  } else {
102    the_thread->cpu_time_budget =
103      rtems_configuration_get_ticks_per_timeslice();
104  }
105
106  context->error = 0;
107  return _Thread_Priority_less_than( current_priority, core_high_prio )
108    || !_Thread_Owns_resources( the_thread );
109}
110
111int pthread_setschedparam(
112  pthread_t           thread,
113  int                 policy,
114  struct sched_param *param
115)
116{
117  Thread_Control                *the_thread;
118  Per_CPU_Control               *cpu_self;
119  POSIX_Set_sched_param_context  context;
120  ISR_lock_Context               lock_context;
121  int                            error;
122
123  if ( param == NULL ) {
124    return EINVAL;
125  }
126
127  error = _POSIX_Thread_Translate_sched_param(
128    policy,
129    param,
130    &context.budget_algorithm,
131    &context.budget_callout
132  );
133  if ( error != 0 ) {
134    return error;
135  }
136
137  context.policy = policy;
138  context.param = param;
139
140  the_thread = _Thread_Get( thread, &lock_context );
141
142  if ( the_thread == NULL ) {
143    return ESRCH;
144  }
145
146  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
147  _ISR_lock_ISR_enable( &lock_context );
148
149  _Thread_Change_priority(
150    the_thread,
151    0,
152    &context,
153    _POSIX_Set_sched_param_filter,
154    false
155  );
156
157  _Thread_Dispatch_enable( cpu_self );
158  return context.error;
159}
Note: See TracBrowser for help on using the repository browser.