c9fe17c5b9b7b6fc039853fd25d443e9d9174480
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / solaris2 / kopensolaris-gnu / sched_priv.c
1 /* Copyright (C) 2008 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by David Bartley <dtbartle@csclub.uwaterloo.ca>, 2008.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <inline-syscall.h>
21 #include "sched_priv.h"
22 #include <sys/priocntl.h>
23 #include <bits/libc-lock.h>
24
25 /* XXX: We don't deal with custom schedulers.  */
26
27 /* XXX: We only set sched_param.sched_priority.  */
28
29 /* TODO: Cleanup errno usage.  */
30
31 /* SCHED_SYS has cid == 0 always. */
32 static pcinfo_t __sched_policies[] = {
33   {-1, "TS", {0}},      /* SCHED_OTHER */
34   {-1, "RT", {0}},      /* SCHED_FIFO */
35   {-1, "RT", {0}},      /* SCHED_RR */
36   {0, "SYS", {0}},      /* SCHED_SYS */
37   {-1, "IA", {0}},      /* SCHED_IA */
38   {-1, "FSS", {0}},     /* SCHED_FSS */
39   {-1, "FX", {0}},      /* SCHED_FX */
40 };
41
42 int __sched_policies_initialized = 0;
43 __libc_lock_define_initialized (static, lock);
44
45 int __sched_policy_to_class (int policy)
46 {
47   if (policy < 0 || policy >= _SCHED_NEXT)
48     {
49       __set_errno (EINVAL);
50       return -1;
51     }
52
53   __libc_lock_lock (lock);
54
55   /* Try to get cid from clname.  */
56   if (__sched_policies[policy].pc_cid == -1)
57     {
58       priocntl (0, 0, PC_GETCID, &__sched_policies[policy]);
59     }
60
61   __libc_lock_unlock (lock);
62
63   return __sched_policies[policy].pc_cid;
64 }
65
66 int __sched_class_to_policy (int cid)
67 {
68   int policy = -1;
69
70   __libc_lock_lock (lock);
71
72   for (int i = 0; i < _SCHED_NEXT; i++)
73     {
74       if (__sched_policies[i].pc_cid == -1)
75         priocntl (0, 0, PC_GETCID, &__sched_policies[i]);
76
77       if (__sched_policies[i].pc_cid == cid)
78         {
79           policy = i;
80           break;
81         }
82     }
83
84   __libc_lock_unlock (lock);
85
86   return policy;
87 }
88
89 int __sched_getparam_id (int idtype, id_t id, int *priority)
90 {
91   pcprio_t prio;
92   prio.pc_op = PC_GETPRIO;
93   int result = priocntl (idtype, id, PC_DOPRIO, &prio);
94   if (result != 0)
95     return errno;
96
97   *priority = prio.pc_val;
98
99   return 0;
100 }
101
102 int __sched_setparam_id (int idtype, id_t id, int priority)
103 {
104   /* We need pc_cid to be valid in the PC_SETPRIO call.  */
105   pcprio_t prio;
106   prio.pc_op = PC_GETPRIO;
107   int result = priocntl (idtype, id, PC_DOPRIO, &prio);
108   if (result != 0)
109     return errno;
110
111   prio.pc_op = PC_SETPRIO;
112   prio.pc_val = priority;
113   result = priocntl (idtype, id, PC_DOPRIO, &prio);
114   if (result != 0)
115     return errno;
116
117   return 0;
118 }
119
120 int __sched_getscheduler_id (int idtype, id_t id, int *policy, int *priority)
121 {
122   pcprio_t prio;
123   prio.pc_op = PC_GETPRIO;
124   int result = priocntl (idtype, id, PC_DOPRIO, &prio);
125   if (result != 0)
126     return errno;
127
128   if (priority)
129     *priority = prio.pc_val;
130   *policy = __sched_class_to_policy (prio.pc_cid);
131
132   return 0;
133 }
134
135 int __sched_setscheduler_id (int idtype, id_t id, int policy, int priority)
136 {
137   pcprio_t prio;
138   prio.pc_op = PC_SETPRIO;
139   prio.pc_val = priority;
140   prio.pc_cid = __sched_policy_to_class (policy);
141   if (prio.pc_cid == -1)
142     return -1;
143
144   int result = priocntl (idtype, id, PC_DOPRIO, &prio);
145   if (result != 0)
146     return errno;
147
148   return 0;
149 }