schedPxLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* schedPxLib.c - scheduling library (POSIX) */
  2. /* Copyright 1984-1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01d,24jan95,rhp  doc: clarify relation between struct sched_param and priority
  8.     19jan95,jdi  doc cleanup.
  9. 01c,01feb94,dvs  documentation cleanup.
  10. 01b,05jan94,kdl  changed include to private/schedP.h; general cleanup.
  11. 01a,04nov93,dvs  written
  12. */
  13. /*
  14. DESCRIPTION: 
  15. This library provides POSIX-compliance scheduling routines.  The routines
  16. in this library allow the user to get and set priorities and scheduling
  17. schemes, get maximum and minimum priority values, and get the time slice
  18. if round-robin scheduling is enabled.
  19. The POSIX standard specifies a priority numbering scheme in which
  20. higher priorities are indicated by larger numbers.  The VxWorks native
  21. numbering scheme is the reverse of this, with higher priorities indicated
  22. by smaller numbers.  For example, in the VxWorks native priority numbering
  23. scheme, the highest priority task has a priority of 0.
  24. In VxWorks, POSIX scheduling interfaces are implemented using the POSIX
  25. priority numbering scheme.  This means that the priority numbers used by
  26. this library f2do notf1 match those reported and used in all the other
  27. VxWorks components.  It is possible to change the priority numbering
  28. scheme used by this library by setting the global variable
  29. `posixPriorityNumbering'.  If this variable is set to FALSE, the VxWorks
  30. native numbering scheme (small number = high priority) is used, and
  31. priority numbers used by this library will match those used by the other
  32. portions of VxWorks.
  33. The routines in this library are compliant with POSIX 1003.1b.  In
  34. particular, task priorities are set and reported through the structure
  35. `sched_setparam', which has a single member:
  36. .CS
  37. struct sched_param /@ Scheduling parameter structure @/
  38.     {
  39.     int sched_priority; /@ scheduling priority @/
  40.     };
  41. .CE
  42. POSIX 1003.1b specifies this indirection to permit future extensions
  43. through the same calling interface.  For example, because
  44. sched_setparam() takes this structure as an argument (rather than
  45. using the priority value directly) its type signature need not change
  46. if future schedulers require other parameters.
  47. INCLUDE FILES: sched.h
  48. SEE ALSO: POSIX 1003.1b document, taskLib
  49. */
  50. /* INCLUDES */
  51. #include "vxWorks.h"
  52. #include "private/schedP.h" /* includes sched.h */
  53. #include "timers.h"
  54. #include "taskLib.h"
  55. #include "drv/timer/timerDev.h"
  56. /* globals */
  57. BOOL posixPriorityNumbering = TRUE; /* default use POSIX numbering */
  58. /* externals */
  59. extern BOOL roundRobinOn; /* BOOL for round-robin scheduling */
  60. extern ULONG roundRobinSlice; /* time slice in ticks for RR sched */
  61. /******************************************************************************
  62. *
  63. * sched_setparam - set a task's priority (POSIX)
  64. *
  65. * This routine sets the priority of a specified task, <tid>.  If <tid> is 0,
  66. * it sets the priority of the calling task.  Valid priority numbers are 0
  67. * through 255.
  68. * The <param> argument is a structure whose member `sched_priority' is
  69. * the integer priority value.  For example, the following program fragment
  70. * sets the calling task's priority to 13 using POSIX interfaces:
  71. * .CS
  72. * #include "sched.h"
  73. *  ...
  74. * struct sched_param AppSchedPrio;
  75. *  ...
  76. * AppSchedPrio.sched_priority = 13;
  77. * if ( sched_setparam (0, &AppSchedPrio) != OK )
  78. *     {
  79. *     ... /@ recovery attempt or abort message @/
  80. *     }
  81. *  ...
  82. * .CE
  83. *
  84. * NOTE: If the global variable 'posixPriorityNumbering' is FALSE, the VxWorks
  85. * native priority numbering scheme is used, in which higher priorities are
  86. * indicated by smaller numbers.  This is different than the priority numbering 
  87. * scheme specified by POSIX, in which higher priorities are indicated by
  88. * larger numbers.
  89. *
  90. * RETURNS: 0 (OK) if successful, or -1 (ERROR) on error.
  91. *
  92. * ERRNO: 
  93. *  EINVAL
  94. *     - scheduling priority is outside valid range.
  95. *  ESRCH
  96. *     - task ID is invalid.
  97. *
  98. */
  99. int sched_setparam
  100.     (
  101.     pid_t  tid, /* task ID */
  102.     const struct sched_param *  param /* scheduling parameter */
  103.     )
  104.     {
  105.     if (taskPrioritySet (tid, PX_VX_PRIORITY_CONVERT (param->sched_priority)) 
  106. == ERROR)
  107. {
  108. /* map errno to that specified by POSIX */
  109. switch (errno)
  110.     {
  111.     case S_taskLib_ILLEGAL_PRIORITY:
  112. errno = EINVAL;
  113. break;
  114.     case S_objLib_OBJ_ID_ERROR:
  115. errno = ESRCH;
  116. break;
  117.     default:
  118. break;  /* No generic error to use */
  119.     }
  120. return (ERROR);
  121. }
  122.     return (OK);
  123.     }
  124. /******************************************************************************
  125. *
  126. * sched_getparam - get the scheduling parameters for a specified task (POSIX)
  127. *
  128. * This routine gets the scheduling priority for a specified task, <tid>.
  129. * If <tid> is 0, it gets the priority of the calling task.  The task's
  130. * priority is copied to the `sched_param' structure pointed to by <param>.
  131. *
  132. * NOTE: If the global variable 'posixPriorityNumbering' is FALSE, the VxWorks
  133. * native priority numbering scheme is used, in which higher priorities are
  134. * indicated by smaller numbers.  This is different than the priority numbering 
  135. * scheme specified by POSIX, in which higher priorities are indicated by
  136. * larger numbers.
  137. *
  138. * RETURNS: 0 (OK) if successful, or -1 (ERROR) on error.
  139. *
  140. * ERRNO: 
  141. *  ESRCH
  142. *     - invalid task ID.
  143. *
  144. */
  145. int sched_getparam
  146.     (
  147.     pid_t  tid, /* task ID */
  148.     struct sched_param * param /* scheduling param to store priority */
  149.     )
  150.     {
  151.     if (taskPriorityGet (tid, &(param->sched_priority)) == ERROR)
  152. {
  153. errno = ESRCH; /* invalid task ID */
  154. return (ERROR);
  155. }
  156.     /* convert priority if necessary */
  157.     param->sched_priority = PX_VX_PRIORITY_CONVERT (param->sched_priority);
  158.     return (OK);
  159.     }
  160. /******************************************************************************
  161. *
  162. * sched_setscheduler - set scheduling policy and scheduling parameters (POSIX)
  163. *
  164. * This routine sets the scheduling policy and scheduling parameters for a
  165. * specified task, <tid>.  If <tid> is 0, it sets the scheduling policy and
  166. * scheduling parameters for the calling task.
  167. *
  168. * Because VxWorks does not set scheduling policies (e.g., round-robin scheduling) on a 
  169. * task-by-task basis, setting a scheduling policy that conflicts with the 
  170. * current system policy simply fails and errno is set to EINVAL.  If the 
  171. * requested scheduling policy is the same as the current system policy, then 
  172. * this routine acts just like sched_setparam().
  173. *
  174. * NOTE: If the global variable 'posixPriorityNumbering' is FALSE, the VxWorks
  175. * native priority numbering scheme is used, in which higher priorities are
  176. * indicated by smaller numbers.  This is different than the priority numbering 
  177. * scheme specified by POSIX, in which higher priorities are indicated by
  178. * larger numbers.
  179. *
  180. * RETURNS: The previous scheduling policy (SCHED_FIFO or SCHED_RR), or 
  181. * -1 (ERROR) on error.
  182. *
  183. * ERRNO:
  184. *  EINVAL
  185. *     - scheduling priority is outside valid range, or it is impossible to set
  186. *       the specified scheduling policy.
  187. *  ESRCH
  188. *     - invalid task ID.
  189. *
  190. */
  191. int sched_setscheduler
  192.     (
  193.     pid_t  tid, /* task ID */
  194.     int  policy, /* scheduling policy requested */
  195.     const struct sched_param * param /* scheduling parameters requested */
  196.     )
  197.     {
  198.     /* currently do not support SCHED_OTHER */
  199.     if (policy == SCHED_OTHER)
  200. {
  201. errno = EINVAL;
  202. return (ERROR);
  203. }
  204.     /* 
  205.      * is requested scheduling policy same as system policy? If not, fail 
  206.      * request. 
  207.      */
  208.     if (((roundRobinOn == TRUE) && (policy != SCHED_RR)) ||
  209. ((roundRobinOn == FALSE) && (policy != SCHED_FIFO)))
  210. {
  211. errno = EINVAL;
  212. return (ERROR);
  213. }
  214.     /* set task priority; don't convert priority number - sched_setparam will */
  215.     /* note that sched_setparam calls taskPrioritySet which validates the tid */
  216.     if (sched_setparam (tid, param) == ERROR)
  217. return (ERROR);
  218.     
  219.     return (OK);
  220.     }
  221. /******************************************************************************
  222. *
  223. * sched_getscheduler - get the current scheduling policy (POSIX)
  224. *
  225. * This routine returns the currents scheduling policy (i.e., SCHED_FIFO 
  226. * or SCHED_RR).  
  227. *
  228. * RETURNS: Current scheduling policy (SCHED_FIFO or SCHED_RR), or -1 (ERROR) 
  229. * on error.
  230. *
  231. * ERRNO: 
  232. *  ESRCH
  233. *     - invalid task ID.
  234. *
  235. */
  236. int sched_getscheduler
  237.     (
  238.     pid_t tid /* task ID */
  239.     )
  240.     {
  241.     /* validate tid */
  242.     if ((taskIdVerify (tid) == ERROR) && (tid != 0))
  243. {
  244. errno = ESRCH;
  245. return (ERROR);
  246. }
  247.     return (roundRobinOn == TRUE ? SCHED_RR : SCHED_FIFO);
  248.     }
  249. /******************************************************************************
  250. *
  251. * sched_yield - relinquish the CPU (POSIX)
  252. *
  253. * This routine forces the running task to give up the CPU.
  254. *
  255. * RETURNS: 0 (OK) if successful, or -1 (ERROR) on error.
  256. *
  257. */
  258. int sched_yield (void)
  259.     {
  260.     return (taskDelay (0));
  261.     }
  262. /******************************************************************************
  263. *
  264. * sched_get_priority_max - get the maximum priority (POSIX)
  265. *
  266. * This routine returns the value of the highest possible task priority for a 
  267. * specified scheduling policy (SCHED_FIFO or SCHED_RR).
  268. *
  269. * NOTE: If the global variable 'posixPriorityNumbering' is FALSE, the VxWorks
  270. * native priority numbering scheme is used, in which higher priorities are
  271. * indicated by smaller numbers.  This is different than the priority numbering 
  272. * scheme specified by POSIX, in which higher priorities are indicated by
  273. * larger numbers.
  274. *
  275. * RETURNS: Maximum priority value, or -1 (ERROR) on error.
  276. *
  277. * ERRNO: 
  278. *  EINVAL
  279. *     - invalid scheduling policy.
  280. *
  281. */
  282. int sched_get_priority_max
  283.     (
  284.     int policy /* scheduling policy */
  285.     )
  286.     {
  287.     /* check if policy is valid */
  288.     if ((policy != SCHED_RR) && (policy != SCHED_FIFO))
  289. {
  290. errno = EINVAL;
  291. return (ERROR);
  292. }
  293.     /* return highest possible priority */
  294.     if (policy == SCHED_RR)
  295. return (PX_NUMBER_CONVERT (SCHED_RR_HIGH_PRI));
  296.     else
  297. return (PX_NUMBER_CONVERT (SCHED_FIFO_HIGH_PRI));
  298.     }    
  299. /******************************************************************************
  300. *
  301. * sched_get_priority_min - get the minimum priority (POSIX)
  302. *
  303. * This routine returns the value of the lowest possible task priority for a 
  304. * specified scheduling policy (SCHED_FIFO or SCHED_RR).
  305. *
  306. * NOTE: If the global variable 'posixPriorityNumbering' is FALSE, the VxWorks
  307. * native priority numbering scheme is used, in which higher priorities are
  308. * indicated by smaller numbers.  This is different than the priority numbering 
  309. * scheme specified by POSIX, in which higher priorities are indicated by
  310. * larger numbers.
  311. *
  312. * RETURNS: Minimum priority value, or -1 (ERROR) on error.
  313. *
  314. * ERRNO: 
  315. *  EINVAL
  316. *     - invalid scheduling policy.
  317. *
  318. */
  319. int sched_get_priority_min
  320.     (
  321.     int policy /* scheduling policy */
  322.     )
  323.     {
  324.     /* check if policy is valid */
  325.     if ((policy != SCHED_RR) && ( policy != SCHED_FIFO))
  326. {
  327. errno = EINVAL;
  328. return (ERROR);
  329. }
  330.     /* return lowest possible priority */
  331.     if (policy == SCHED_RR)
  332. return (PX_NUMBER_CONVERT (SCHED_RR_LOW_PRI));
  333.     else
  334. return (PX_NUMBER_CONVERT (SCHED_FIFO_LOW_PRI));
  335.     }    
  336. /******************************************************************************
  337. *
  338. * sched_rr_get_interval - get the current time slice (POSIX)
  339. *
  340. * This routine sets <interval> to the current time slice period if round-robin
  341. * scheduling is currently enabled. 
  342. *
  343. * RETURNS: 0 (OK) if successful, -1 (ERROR) on error.
  344. *
  345. * ERRNO: 
  346. *  EINVAL
  347. *     - round-robin scheduling is not currently enabled.
  348. *  ESRCH
  349. *     - invalid task ID.
  350. *
  351. * INTERNAL: A slight race condition could exist between the time that
  352. * we check that round-robin is on and when we get and report the time slice.
  353. *
  354. */
  355. int sched_rr_get_interval
  356.     (
  357.     pid_t tid, /* task ID */
  358.     struct timespec *  interval /* struct to store time slice */
  359.     )
  360.     {
  361.     time_t rate; /* clock rate in ticks */
  362.     time_t timeSlice; /* time slice in ticks */
  363.     /* validate tid - tid = 0 references current task */
  364.     if ((taskIdVerify (tid) == ERROR) && (tid != 0))
  365. {
  366. errno = ESRCH;
  367. return (ERROR);
  368. }
  369.     /* validate that round-robin is on */
  370.     if (roundRobinOn != TRUE)
  371. {
  372. errno = EINVAL;
  373. return (ERROR);
  374. }
  375.     /* get clock rate and time slice */
  376.     rate = sysClkRateGet();
  377.     timeSlice = roundRobinSlice;
  378.     /* convert ticks to seconds/nanoseconds */
  379.     interval->tv_sec = (time_t) (timeSlice / rate);
  380.     interval->tv_nsec = (timeSlice % rate) * (1000000000 / rate);
  381.     return (OK);
  382.     }