Go to the documentation of this file.00001
00008
00009
00010
00011
00012 #include <ecl/config/ecl.hpp>
00013 #if defined(ECL_IS_POSIX)
00014
00015
00016
00017
00018
00019 #include <iostream>
00020 #include <unistd.h>
00021 #include <ecl/errors/handlers.hpp>
00022 #include "../../include/ecl/threads/priority_pos.hpp"
00023
00024
00025
00026
00027
00028 namespace ecl {
00029
00030
00031
00032
00033
00034 using std::ostringstream;
00035
00036
00037
00038
00039
00040 bool set_priority(Priority priority_level) ecl_debug_throw_decl(StandardException)
00041 {
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 if ( priority_level >= RealTimePriority1 ) {
00059 #if _POSIX_PRIORITY_SCHEDULING > 0
00060 int rr_min = sched_get_priority_min(SCHED_RR); int rr_max = sched_get_priority_max(SCHED_RR);
00061 if ( ( rr_min == -1 ) || (rr_max == -1) ) {
00062 ecl_throw(StandardException(LOC,NotSupportedError,"The posix SCHED_RR policy is not available on this system [sched_get_priority_min/max]."));
00063 return false;
00064 }
00065 ecl_try {
00066
00067 if ( !threads::set_real_time_priority(SCHED_RR,rr_min+(priority_level - RealTimePriority1)*(rr_max - rr_min)/10) ) {
00068 return false;
00069 }
00070 } ecl_catch(StandardException &e ) {
00071 ecl_throw(StandardException(e));
00072 }
00073 #else
00074 ecl_throw(StandardException(LOC,NotSupportedError,"Your version of posix does not support real time priority scheduling for process management."));
00075 return false;
00076 #endif
00077 return true;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 int return_value = 0;
00087
00088 switch (priority_level) {
00089 case CriticalPriority : {
00090 return_value = setpriority(PRIO_PROCESS,0,PRIO_MIN);
00091 break;
00092 }
00093 case HighPriority : {
00094 setpriority(PRIO_PROCESS,0,PRIO_MIN + (PRIO_MAX-PRIO_MIN)/4);
00095 break;
00096 }
00097 case NormalPriority : {
00098 setpriority(PRIO_PROCESS,0,PRIO_MIN + (PRIO_MAX-PRIO_MIN)/2);
00099 break;
00100 }
00101 case LowPriority : {
00102 setpriority(PRIO_PROCESS,0,PRIO_MIN + 3*(PRIO_MAX-PRIO_MIN)/4);
00103 break;
00104 }
00105 case BackgroundPriority : {
00106 setpriority(PRIO_PROCESS,0,PRIO_MAX);
00107 break;
00108 }
00109 default : {
00110
00111 break;
00112 }
00113 }
00114 if ( return_value == -1 ) {
00115 ecl_debug_throw(threads::throwPriorityException(LOC));
00116 return false;
00117 }
00118 return true;
00119 }
00120
00121 Priority get_priority() ecl_debug_throw_decl(StandardException)
00122 {
00123
00124
00125
00126 #if _POSIX_PRIORITY_SCHEDULING > 0
00127 int scheduler = sched_getscheduler(0);
00128 switch ( scheduler ) {
00129 case ( -1 ) : {
00130 ecl_debug_throw(threads::throwPriorityException(LOC));
00131 return UnknownPriority;
00132 break;
00133 }
00134 case ( SCHED_OTHER ) : {
00135
00136 break;
00137 }
00138 case ( SCHED_RR ) : {
00139
00140
00141
00142 sched_param param;
00143 if ( sched_getparam(0,¶m) != 0 ) {
00144 ecl_debug_throw(threads::throwPriorityException(LOC));
00145 return UnknownPriority;
00146 }
00147 int rr_min = sched_get_priority_min(SCHED_RR);
00148 int rr_max = sched_get_priority_max(SCHED_RR);
00149 if ( ( rr_min == -1 ) || (rr_max == -1) ) {
00150 ecl_throw(StandardException(LOC,NotSupportedError,"The posix SCHED_RR policy is not available on this system [sched_get_priority_min/max]."));
00151 return UnknownPriority;
00152 }
00153 if ( param.sched_priority >= rr_min + 3*(rr_max-rr_min)/10 ) {
00154 return RealTimePriority4;
00155 } else if ( param.sched_priority >= rr_min + 2*(rr_max-rr_min)/10 ) {
00156 return RealTimePriority3;
00157 } else if ( param.sched_priority >= rr_min + (rr_max-rr_min)/10 ) {
00158 return RealTimePriority2;
00159 } else {
00160 return RealTimePriority1;
00161 }
00162 break;
00163 }
00164 case ( SCHED_FIFO ) : { return UnknownPriority; }
00165 #if defined(SCHED_BATCH) // Didn't turn up on an old gcc3 with an arm pax270 board.
00166 case ( SCHED_BATCH ) : { return UnknownPriority; }
00167 #endif
00168 default : { return UnknownPriority; }
00169 }
00170 #endif
00171
00172
00173
00174 switch ( getpriority(PRIO_PROCESS,0) ) {
00175 case (PRIO_MIN) : { return CriticalPriority; }
00176 case (PRIO_MIN + (PRIO_MAX-PRIO_MIN)/4) : { return HighPriority; }
00177 case (PRIO_MIN + (PRIO_MAX-PRIO_MIN)/2) : { return NormalPriority; }
00178 case (PRIO_MIN + 3*(PRIO_MAX-PRIO_MIN)/4) : { return LowPriority; }
00179 case (PRIO_MAX) : { return BackgroundPriority; }
00180 default : return NormalPriority;
00181 }
00182
00183 }
00184
00185
00186
00187
00188 std::string print_priority_diagnostics() ecl_debug_throw_decl(StandardException) {
00189
00190 ostringstream ostream;
00191
00192 ostream << "\n";
00193 ostream << "***********************************************************\n";
00194 ostream << "* System Statistics\n";
00195 ostream << "***********************************************************\n";
00196 ostream << "\n";
00197
00198 #if _POSIX_PRIORITY_SCHEDULING > 0
00199 int rr_min = sched_get_priority_min(SCHED_RR);
00200 int rr_max = sched_get_priority_max(SCHED_RR);
00201 if ( ( rr_min == -1 ) || (rr_max == -1) ) {
00202 ecl_throw(StandardException(LOC,NotSupportedError,"The posix SCHED_RR policy is not available on this system [sched_get_priority_min/max]."));
00203 return std::string("The posix SCHED_RR policy is not available on this system [sched_get_priority_min/max].");
00204 }
00205 ostream << "Real Time Priorities [Low,High]............[" << rr_min << "," << rr_max << "]\n";
00206 #endif
00207 ostream << "Niceness [Low,High]........................[" << PRIO_MAX << "," << PRIO_MIN << "]\n";
00208 ostream << "\n";
00209 ostream << "***********************************************************\n";
00210 ostream << "* Priority Statistics\n";
00211 ostream << "***********************************************************\n";
00212 ostream << "\n";
00213 #if _POSIX_PRIORITY_SCHEDULING > 0
00214 int scheduler = sched_getscheduler(0);
00215 switch ( scheduler ) {
00216 case ( -1 ) : {
00217 ecl_debug_throw(threads::throwPriorityException(LOC));
00218 return std::string("Call to sched_getscheduler failed.");
00219 }
00220 case ( SCHED_OTHER ) : {
00221 ostream << "Scheduler..................................SCHED_OTHER" << "\n";
00222 break;
00223 }
00224 case ( SCHED_RR ) : {
00225 ostream << "Scheduler..................................SCHED_RR [RT]" << "\n";
00226 break;
00227 }
00228 case ( SCHED_FIFO ) : {
00229 ostream << "Scheduler..................................SCHED_FIFO [RT]" << "\n";
00230 break;
00231 }
00232 #if defined(SCHED_BATCH)
00233 case ( SCHED_BATCH ) : {
00234 ostream << "Scheduler..................................SCHED_BATCH" << "\n";
00235 break;
00236 }
00237 #endif
00238 default : {
00239 ostream << "Scheduler..................................Unknown" << "\n";
00240 break;
00241 }
00242 }
00243 #endif
00244 switch ( get_priority() ) {
00245 case ( BackgroundPriority ) : {
00246 ostream << "Priority...................................Background\n";
00247 break;
00248 }
00249 case ( LowPriority ) : {
00250 ostream << "Priority...................................Low\n";
00251 break;
00252 }
00253 case ( NormalPriority ) : {
00254 ostream << "Priority...................................Normal\n";
00255 break;
00256 }
00257 case ( HighPriority ) : {
00258 ostream << "Priority...................................High\n";
00259 break;
00260 }
00261 case ( CriticalPriority ) : {
00262 ostream << "Priority...................................Critical\n";
00263 break;
00264 }
00265 case ( RealTimePriority4 ) : {
00266 ostream << "Priority...................................RealTime4\n";
00267 break;
00268 }
00269 case ( RealTimePriority3 ) : {
00270 ostream << "Priority...................................RealTime3\n";
00271 break;
00272 }
00273 case ( RealTimePriority2 ) : {
00274 ostream << "Priority...................................RealTime2\n";
00275 break;
00276 }
00277 case ( RealTimePriority1 ) : {
00278 ostream << "Priority...................................RealTime1\n";
00279 break;
00280 }
00281 case ( DefaultPriority ) : {
00282 ostream << "Priority...................................Default (Inherited)\n";
00283 break;
00284 }
00285 case ( UnknownPriority ) : {
00286 ostream << "Priority...................................Unknown\n";
00287 break;
00288 }
00289 }
00290 return ostream.str();
00291 }
00292
00293
00294
00295
00296
00297
00298 namespace threads {
00299
00300 bool set_real_time_priority(int policy,int priority_level) ecl_debug_throw_decl(StandardException) {
00301
00302 #if _POSIX_PRIORITY_SCHEDULING > 0
00303 ostringstream ostream;
00304
00305
00306
00307
00308 if ( priority_level < sched_get_priority_min(policy) ) {
00309 ostream << "The realtime process priority requested was smaller than the minimum value permitted[";
00310 ostream << sched_get_priority_min(policy) << "]\n";
00311 ecl_throw(StandardException(LOC,OutOfRangeError, ostream.str()));
00312 return false;
00313 } else if (priority_level > sched_get_priority_max(policy) ) {
00314 ostream << "The realtime process priority requested was greater than the maximum value permitted[";
00315 ostream << sched_get_priority_max(policy) << "]\n";
00316 ecl_throw(StandardException(LOC,OutOfRangeError, ostream.str()));
00317 return false;
00318 }
00319
00320
00321
00322
00323 sched_param schedule_parameters;
00324 schedule_parameters.sched_priority = priority_level;
00325 if ( sched_setscheduler(0, policy, &schedule_parameters) == -1 ) {
00326 ecl_debug_throw(throwPriorityException(LOC));
00327 return false;
00328 }
00329 return true;
00330 #else
00331 ecl_throw(StandardException(LOC,ecl::NotSupportedError,"Your version of posix does not support real time priority scheduling for process management."));
00332 return false;
00333 #endif
00334 }
00335 }
00336 };
00337
00338 #endif