master
1/*
2 Copyright (c) 2011-2016 mingw-w64 project
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
21*/
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include <stdio.h>
28
29#define WIN32_LEAN_AND_MEAN
30#include <windows.h>
31
32/* public header files */
33#include "pthread.h"
34/* internal header files */
35#include "misc.h"
36#include "thread.h"
37
38int sched_get_priority_min(int pol)
39{
40 if (pol < SCHED_MIN || pol > SCHED_MAX) {
41 errno = EINVAL;
42 return -1;
43 }
44
45 return THREAD_PRIORITY_IDLE;
46}
47
48int sched_get_priority_max(int pol)
49{
50 if (pol < SCHED_MIN || pol > SCHED_MAX) {
51 errno = EINVAL;
52 return -1;
53 }
54
55 return THREAD_PRIORITY_TIME_CRITICAL;
56}
57
58int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *p)
59{
60 int r = 0;
61
62 if (attr == NULL || p == NULL) {
63 return EINVAL;
64 }
65 memcpy(&attr->param, p, sizeof (*p));
66 return r;
67}
68
69int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *p)
70{
71 int r = 0;
72
73 if (attr == NULL || p == NULL) {
74 return EINVAL;
75 }
76 memcpy(p, &attr->param, sizeof (*p));
77 return r;
78}
79
80int pthread_attr_setschedpolicy (pthread_attr_t *attr, int pol)
81{
82 if (!attr || pol < SCHED_MIN || pol > SCHED_MAX)
83 return EINVAL;
84 if (pol != SCHED_OTHER)
85 return ENOTSUP;
86 return 0;
87}
88
89int pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *pol)
90{
91 if (!attr || !pol)
92 return EINVAL;
93 *pol = SCHED_OTHER;
94 return 0;
95}
96
97static int pthread_check(pthread_t t)
98{
99 struct _pthread_v *pv;
100
101 if (!t)
102 return ESRCH;
103 pv = __pth_gpointer_locked (t);
104 if (pv->ended == 0)
105 return 0;
106 CHECK_OBJECT(pv, ESRCH);
107 return 0;
108}
109
110int pthread_getschedparam(pthread_t t, int *pol, struct sched_param *p)
111{
112 int r;
113 //if (!t)
114 // t = pthread_self();
115
116 if ((r = pthread_check(t)) != 0)
117 {
118 return r;
119 }
120
121 if (!p || !pol)
122 {
123 return EINVAL;
124 }
125 *pol = __pth_gpointer_locked (t)->sched_pol;
126 p->sched_priority = __pth_gpointer_locked (t)->sched.sched_priority;
127
128 return 0;
129}
130
131int pthread_setschedparam(pthread_t t, int pol, const struct sched_param *p)
132{
133 struct _pthread_v *pv;
134 int r, pr = 0;
135 //if (!t.p) t = pthread_self();
136
137 if ((r = pthread_check(t)) != 0)
138 return r;
139
140 if (pol < SCHED_MIN || pol > SCHED_MAX || p == NULL)
141 return EINVAL;
142 if (pol != SCHED_OTHER)
143 return ENOTSUP;
144 pr = p->sched_priority;
145 if (pr < sched_get_priority_min(pol) || pr > sched_get_priority_max(pol))
146 return EINVAL;
147
148 /* See msdn: there are actually 7 priorities:
149 THREAD_PRIORITY_IDLE - -15
150 THREAD_PRIORITY_LOWEST -2
151 THREAD_PRIORITY_BELOW_NORMAL -1
152 THREAD_PRIORITY_NORMAL 0
153 THREAD_PRIORITY_ABOVE_NORMAL 1
154 THREAD_PRIORITY_HIGHEST 2
155 THREAD_PRIORITY_TIME_CRITICAL 15
156 */
157 if (pr <= THREAD_PRIORITY_IDLE) {
158 pr = THREAD_PRIORITY_IDLE;
159 } else if (pr <= THREAD_PRIORITY_LOWEST) {
160 pr = THREAD_PRIORITY_LOWEST;
161 } else if (pr >= THREAD_PRIORITY_TIME_CRITICAL) {
162 pr = THREAD_PRIORITY_TIME_CRITICAL;
163 } else if (pr >= THREAD_PRIORITY_HIGHEST) {
164 pr = THREAD_PRIORITY_HIGHEST;
165 }
166 pv = __pth_gpointer_locked (t);
167 if (SetThreadPriority(pv->h, pr)) {
168 pv->sched_pol = pol;
169 pv->sched.sched_priority = p->sched_priority;
170 } else
171 r = EINVAL;
172 return r;
173}
174
175int sched_getscheduler(pid_t pid)
176{
177 if (pid != 0)
178 {
179 HANDLE h = NULL;
180 int selfPid = (int) GetCurrentProcessId ();
181
182 if (pid != (pid_t) selfPid && (h = OpenProcess (PROCESS_QUERY_INFORMATION, 0, (DWORD) pid)) == NULL)
183 {
184 errno = (GetLastError () == (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
185 return -1;
186 }
187 if (h)
188 CloseHandle (h);
189 }
190 return SCHED_OTHER;
191}
192
193int sched_setscheduler(pid_t pid, int pol, const struct sched_param *param)
194{
195 if (!param)
196 {
197 errno = EINVAL;
198 return -1;
199 }
200 if (pid != 0)
201 {
202 HANDLE h = NULL;
203 int selfPid = (int) GetCurrentProcessId ();
204
205 if (pid != (pid_t) selfPid && (h = OpenProcess (PROCESS_SET_INFORMATION, 0, (DWORD) pid)) == NULL)
206 {
207 errno = (GetLastError () == (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
208 return -1;
209 }
210 if (h)
211 CloseHandle (h);
212 }
213
214 if (pol != SCHED_OTHER)
215 {
216 errno = ENOSYS;
217 return -1;
218 }
219 return SCHED_OTHER;
220}
221
222int sched_yield(void)
223{
224 Sleep(0);
225 return 0;
226}