| 1 |
/* |
| 2 |
* Module: sched.h |
| 3 |
* |
| 4 |
* Purpose: |
| 5 |
* Provides an implementation of POSIX realtime extensions |
| 6 |
* as defined in |
| 7 |
* |
| 8 |
* POSIX 1003.1b-1993 (POSIX.1b) |
| 9 |
* |
| 10 |
* -------------------------------------------------------------------------- |
| 11 |
* |
| 12 |
* Pthreads-win32 - POSIX Threads Library for Win32 |
| 13 |
* Copyright(C) 1998 John E. Bossom |
| 14 |
* Copyright(C) 1999,2012 Pthreads-win32 contributors |
| 15 |
* |
| 16 |
* Homepage1: http://sourceware.org/pthreads-win32/ |
| 17 |
* Homepage2: http://sourceforge.net/projects/pthreads4w/ |
| 18 |
* |
| 19 |
* The current list of contributors is contained |
| 20 |
* in the file CONTRIBUTORS included with the source |
| 21 |
* code distribution. The list can also be seen at the |
| 22 |
* following World Wide Web location: |
| 23 |
* http://sources.redhat.com/pthreads-win32/contributors.html |
| 24 |
* |
| 25 |
* This library is free software; you can redistribute it and/or |
| 26 |
* modify it under the terms of the GNU Lesser General Public |
| 27 |
* License as published by the Free Software Foundation; either |
| 28 |
* version 2 of the License, or (at your option) any later version. |
| 29 |
* |
| 30 |
* This library is distributed in the hope that it will be useful, |
| 31 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 32 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 33 |
* Lesser General Public License for more details. |
| 34 |
* |
| 35 |
* You should have received a copy of the GNU Lesser General Public |
| 36 |
* License along with this library in the file COPYING.LIB; |
| 37 |
* if not, write to the Free Software Foundation, Inc., |
| 38 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
| 39 |
*/ |
| 40 |
#ifndef _SCHED_H |
| 41 |
#define _SCHED_H |
| 42 |
#define __SCHED_H_SOURCED__ |
| 43 |
|
| 44 |
#include <_ptw32.h> |
| 45 |
|
| 46 |
/* We need a typedef for pid_t, (and POSIX requires <sched.h> to |
| 47 |
* define it, as it is defined in <sys/types.h>, but it does NOT |
| 48 |
* sanction exposure of everything from <sys/types.h>); there is |
| 49 |
* no pid_t in Windows anyway, (except that MinGW does define it |
| 50 |
* in their <sys/types.h>), so just provide a suitable typedef, |
| 51 |
* but note that we must do so cautiously, to avoid a typedef |
| 52 |
* conflict if MinGW's <sys/types.h> is also #included: |
| 53 |
*/ |
| 54 |
#if !(defined __MINGW32__ && defined __have_typedef_pid_t) |
| 55 |
|
| 56 |
typedef int pid_t; |
| 57 |
|
| 58 |
#if __GNUC__ < 4 |
| 59 |
/* GCC v4.0 and later, (as used by MinGW), allows us to repeat a |
| 60 |
* typedef, provided every duplicate is consistent; only set this |
| 61 |
* multiple definition guard when we cannot be certain that it is |
| 62 |
* permissable to repeat typedefs. |
| 63 |
*/ |
| 64 |
#define __have_typedef_pid_t 1 |
| 65 |
#endif |
| 66 |
#endif |
| 67 |
|
| 68 |
/* POSIX.1-1993 says that <sched.h> WILL expose all of <time.h> |
| 69 |
*/ |
| 70 |
#if _POSIX_C_SOURCE >= 200112L |
| 71 |
/* POSIX.1-2001 and later revises this to say only that it MAY do so; |
| 72 |
* only struct timespec, and associated time_t are actually required, |
| 73 |
* so prefer to be selective; (MinGW.org's <time.h> offers an option |
| 74 |
* for selective #inclusion, when __SCHED_H_SOURCED__ is defined): |
| 75 |
*/ |
| 76 |
#define __need_struct_timespec |
| 77 |
#define __need_time_t |
| 78 |
#endif |
| 79 |
#include <time.h> |
| 80 |
|
| 81 |
#if defined __MINGW64__ || _MSC_VER >= 1900 |
| 82 |
/* These are known to define struct timespec, when <time.h> has been |
| 83 |
* #included, but may not, (probably don't), follow the convention of |
| 84 |
* defining __struct_timespec_defined, as adopted by MinGW.org; for |
| 85 |
* these cases, we unconditionally assume that struct timespec has |
| 86 |
* been defined, otherwise, if MinGW.org's criterion has not been |
| 87 |
* satisfied... |
| 88 |
*/ |
| 89 |
#elif !(defined __struct_timespec_defined || defined _TIMESPEC_DEFINED) |
| 90 |
struct timespec |
| 91 |
{ /* ...we fall back on this explicit definition. |
| 92 |
*/ |
| 93 |
time_t tv_sec; |
| 94 |
int tv_nsec; |
| 95 |
}; |
| 96 |
# define _TIMESPEC_DEFINED |
| 97 |
#endif |
| 98 |
|
| 99 |
/* |
| 100 |
* Microsoft VC++6.0 lacks these *_PTR types |
| 101 |
*/ |
| 102 |
#if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_PTW32_HAVE_DWORD_PTR) |
| 103 |
typedef unsigned long ULONG_PTR; |
| 104 |
typedef ULONG_PTR DWORD_PTR; |
| 105 |
#endif |
| 106 |
|
| 107 |
/* Thread scheduling policies */ |
| 108 |
|
| 109 |
enum |
| 110 |
{ SCHED_OTHER = 0, |
| 111 |
SCHED_FIFO, |
| 112 |
SCHED_RR, |
| 113 |
SCHED_MIN = SCHED_OTHER, |
| 114 |
SCHED_MAX = SCHED_RR |
| 115 |
}; |
| 116 |
|
| 117 |
struct sched_param |
| 118 |
{ int sched_priority; |
| 119 |
}; |
| 120 |
|
| 121 |
/* CPU affinity |
| 122 |
* |
| 123 |
* cpu_set_t: |
| 124 |
* Considered opaque but cannot be an opaque pointer due to the need for |
| 125 |
* compatibility with GNU systems and sched_setaffinity() et.al., which |
| 126 |
* include the cpusetsize parameter "normally set to sizeof(cpu_set_t)". |
| 127 |
* |
| 128 |
* FIXME: These are GNU, and NOT specified by POSIX; they gratuitously |
| 129 |
* assume that size_t is defined, which is also not required in a POSIX |
| 130 |
* conforming <sched.h>. The latter requirement may be satisfied, for |
| 131 |
* GCC users, by selective inclusion from <stddef.h>, (and by inclusion |
| 132 |
* of <stdlib.h> for other compilers); also, maybe consider occluding |
| 133 |
* all of this within a _GNU_SOURCE (or similar) feature test. |
| 134 |
*/ |
| 135 |
#ifdef __GNUC__ |
| 136 |
# define __need_size_t |
| 137 |
# include <stddef.h> |
| 138 |
#else |
| 139 |
# include <stdlib.h> |
| 140 |
#endif |
| 141 |
#define CPU_SETSIZE (sizeof(size_t)*8) |
| 142 |
#define CPU_COUNT(setptr) (_sched_affinitycpucount(setptr)) |
| 143 |
#define CPU_ZERO(setptr) (_sched_affinitycpuzero(setptr)) |
| 144 |
#define CPU_SET(cpu, setptr) (_sched_affinitycpuset((cpu),(setptr))) |
| 145 |
#define CPU_CLR(cpu, setptr) (_sched_affinitycpuclr((cpu),(setptr))) |
| 146 |
#define CPU_ISSET(cpu, setptr) (_sched_affinitycpuisset((cpu),(setptr))) |
| 147 |
|
| 148 |
#define CPU_AND(destsetptr, srcset1ptr, srcset2ptr) \ |
| 149 |
(_sched_affinitycpuand((destsetptr),(srcset1ptr),(srcset2ptr))) |
| 150 |
|
| 151 |
#define CPU_OR(destsetptr, srcset1ptr, srcset2ptr) \ |
| 152 |
(_sched_affinitycpuor((destsetptr),(srcset1ptr),(srcset2ptr))) |
| 153 |
|
| 154 |
#define CPU_XOR(destsetptr, srcset1ptr, srcset2ptr) \ |
| 155 |
(_sched_affinitycpuxor((destsetptr),(srcset1ptr),(srcset2ptr))) |
| 156 |
|
| 157 |
#define CPU_EQUAL(set1ptr, set2ptr) \ |
| 158 |
(_sched_affinitycpuequal((set1ptr),(set2ptr))) |
| 159 |
|
| 160 |
typedef union |
| 161 |
{ char cpuset[CPU_SETSIZE/8]; |
| 162 |
size_t _align; |
| 163 |
} cpu_set_t; |
| 164 |
|
| 165 |
__PTW32_BEGIN_C_DECLS |
| 166 |
|
| 167 |
__PTW32_DECLSPEC int sched_yield (void); |
| 168 |
__PTW32_DECLSPEC int sched_get_priority_min (int); |
| 169 |
__PTW32_DECLSPEC int sched_get_priority_max (int); |
| 170 |
|
| 171 |
/* FIXME: this declaration of sched_setscheduler() is NOT as prescribed |
| 172 |
* by POSIX; it lacks const struct sched_param * as third argument. |
| 173 |
*/ |
| 174 |
__PTW32_DECLSPEC int sched_setscheduler (pid_t, int); |
| 175 |
|
| 176 |
/* FIXME: In addition to the above five functions, POSIX also requires: |
| 177 |
* |
| 178 |
* int sched_getparam (pid_t, struct sched_param *); |
| 179 |
* int sched_setparam (pid_t, const struct sched_param *); |
| 180 |
* |
| 181 |
* both of which are conspicuous by their absence here! |
| 182 |
*/ |
| 183 |
|
| 184 |
/* Compatibility with Linux - not standard in POSIX |
| 185 |
* FIXME: consider occluding within a _GNU_SOURCE (or similar) feature test. |
| 186 |
*/ |
| 187 |
__PTW32_DECLSPEC int sched_setaffinity (pid_t, size_t, cpu_set_t *); |
| 188 |
__PTW32_DECLSPEC int sched_getaffinity (pid_t, size_t, cpu_set_t *); |
| 189 |
|
| 190 |
/* Support routines and macros for cpu_set_t |
| 191 |
*/ |
| 192 |
__PTW32_DECLSPEC int _sched_affinitycpucount (const cpu_set_t *); |
| 193 |
__PTW32_DECLSPEC void _sched_affinitycpuzero (cpu_set_t *); |
| 194 |
__PTW32_DECLSPEC void _sched_affinitycpuset (int, cpu_set_t *); |
| 195 |
__PTW32_DECLSPEC void _sched_affinitycpuclr (int, cpu_set_t *); |
| 196 |
__PTW32_DECLSPEC int _sched_affinitycpuisset (int, const cpu_set_t *); |
| 197 |
__PTW32_DECLSPEC void _sched_affinitycpuand (cpu_set_t *, const cpu_set_t *, const cpu_set_t *); |
| 198 |
__PTW32_DECLSPEC void _sched_affinitycpuor (cpu_set_t *, const cpu_set_t *, const cpu_set_t *); |
| 199 |
__PTW32_DECLSPEC void _sched_affinitycpuxor (cpu_set_t *, const cpu_set_t *, const cpu_set_t *); |
| 200 |
__PTW32_DECLSPEC int _sched_affinitycpuequal (const cpu_set_t *, const cpu_set_t *); |
| 201 |
|
| 202 |
/* Note that this macro returns ENOTSUP rather than ENOSYS, as |
| 203 |
* might be expected. However, returning ENOSYS should mean that |
| 204 |
* sched_get_priority_{min,max} are not implemented as well as |
| 205 |
* sched_rr_get_interval. This is not the case, since we just |
| 206 |
* don't support round-robin scheduling. Therefore I have chosen |
| 207 |
* to return the same value as sched_setscheduler when SCHED_RR |
| 208 |
* is passed to it. |
| 209 |
* |
| 210 |
* FIXME: POSIX requires this to be defined as a function; this |
| 211 |
* macro implementation is permitted IN ADDITION to the function, |
| 212 |
* but the macro alone is not POSIX compliant! Worse still, it |
| 213 |
* imposes a requirement on the caller, to ensure that both the |
| 214 |
* declaration of errno, and the definition of ENOTSUP, are in |
| 215 |
* scope at point of call, (which it may wish to do anyway, but |
| 216 |
* POSIX imposes no such constraint)! |
| 217 |
*/ |
| 218 |
#define sched_rr_get_interval(_pid, _interval) \ |
| 219 |
( errno = ENOTSUP, (int) -1 ) |
| 220 |
|
| 221 |
__PTW32_END_C_DECLS |
| 222 |
|
| 223 |
#undef __SCHED_H_SOURCED__ |
| 224 |
#endif /* !_SCHED_H */ |