diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index fe2931733..8de0be39e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,26 @@ +2005-01-25 Corinna Vinschen + + * cygwin.din: Export getpriority and setpriority. + * fork.cc (fork_parent): Copy parent's nice value into child. + * spawn.cc (spawn_guts): Ditto. + * miscfuncs.cc (winprio_to_nice): New function. + (nice_to_winprio): Ditto. + * pinfo.cc (pinfo_init): If parent is not a Cygwin process, set + default nice value according to current Win32 priority class. + * pinfo.h (class _pinfo): Add nice member. + * syscalls.cc (setpriority): New function, only implementing + PRIO_PROCESS for now. + (getpriority): Ditto. + (nice): Just call setpriority. + * wincap.h (wincaps::has_extended_priority_class): New element. + * wincap.cc: Implement above element throughout. + * winsup.h: Add prototypes for winprio_to_nice and nice_to_winprio. + * include/limits.h (NZERO): New define. + * include/cygwin/types.h (id_t): New datatype. + * include/cygwin/version.h: Bump API minor version. + * include/sys/resource.h: Add PRIO_XXX defines and prototypes for + getpriority and setpriority. + 2005-01-25 Corinna Vinschen * path.cc (realpath): Allow to expand with .exe suffix. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 666d7705c..6f0acb787 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -653,6 +653,7 @@ getpid NOSIGFE _getpid = getpid NOSIGFE getppid NOSIGFE _getppid = getppid NOSIGFE +getpriority NOSIGFE getpwduid NOSIGFE _getpwduid = getpwduid NOSIGFE getpwent SIGFE @@ -1198,6 +1199,7 @@ setpgid SIGFE _setpgid = setpgid SIGFE setpgrp SIGFE _setpgrp = setpgrp SIGFE +setpriority NOSIGFE setpwent NOSIGFE _setpwent = setpwent NOSIGFE setregid SIGFE diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index b46d0329f..85d5728a5 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -383,6 +383,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, int child_pid = cygwin_pid (pi.dwProcessId); pinfo child (child_pid, 1); child->start_time = time (NULL); /* Register child's starting time. */ + child->nice = myself->nice; if (!child) { diff --git a/winsup/cygwin/include/cygwin/types.h b/winsup/cygwin/include/cygwin/types.h index aaa0f67f1..3964ae3a9 100644 --- a/winsup/cygwin/include/cygwin/types.h +++ b/winsup/cygwin/include/cygwin/types.h @@ -99,6 +99,12 @@ typedef __ino32_t ino_t; #endif #endif /*__ino_t_defined*/ +/* Generic ID type, must match at least pid_t, uid_t and gid_t in size. */ +#ifndef __id_t_defined +#define __id_t_defined +typedef unsigned long id_t; +#endif /* __id_t_defined */ + #if defined (__INSIDE_CYGWIN__) struct __flock32 { short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index f81bc2afc..c38fc5520 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -245,12 +245,13 @@ details. */ getlogin_r. 116: Export atoll. 117: Export utmpx functions, Return utmp * from pututent. + 118: Export getpriority, setpriority. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 117 +#define CYGWIN_VERSION_API_MINOR 118 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/limits.h b/winsup/cygwin/include/limits.h index 25136acdf..5ef3513ce 100644 --- a/winsup/cygwin/include/limits.h +++ b/winsup/cygwin/include/limits.h @@ -182,5 +182,8 @@ details. */ #define RTSIG_MAX _POSIX_RTSIG_MAX +/* Used for nice and get/setpriority. */ +#define NZERO 20 + #endif /* _MACH_MACHLIMITS_H_ */ #endif /* _LIMITS_H___ */ diff --git a/winsup/cygwin/include/sys/resource.h b/winsup/cygwin/include/sys/resource.h index c1fe544a9..d2de569cd 100644 --- a/winsup/cygwin/include/sys/resource.h +++ b/winsup/cygwin/include/sys/resource.h @@ -17,6 +17,11 @@ details. */ extern "C" { #endif +/* Used for get/setpriority */ +#define PRIO_PROCESS 0 +#define PRIO_PGRP 1 +#define PRIO_USER 2 + #define RLIMIT_CPU 0 /* CPU time in seconds */ #define RLIMIT_FSIZE 1 /* Maximum filesize */ #define RLIMIT_DATA 2 /* max data size */ @@ -68,6 +73,9 @@ int setrlimit (int __resource, const struct rlimit *__rlp); int getrusage (int __who, struct rusage *__rusage); +int getpriority (int which, id_t who); +int setpriority (int which, id_t who, int value); + #ifdef __cplusplus } #endif diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index dcbe7c1b8..720c0bb08 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -356,3 +356,87 @@ low_priority_sleep (DWORD secs) return curr_prio; } + +/* Get a default value for the nice factor. When changing these values, + have a look into the below function nice_to_winprio. The values must + match the layout of the static "priority" array. */ +int +winprio_to_nice (DWORD prio) +{ + switch (prio) + { + case REALTIME_PRIORITY_CLASS: + return -20; + case HIGH_PRIORITY_CLASS: + return -16; + case ABOVE_NORMAL_PRIORITY_CLASS: + return -8; + case NORMAL_PRIORITY_CLASS: + return 0; + case BELOW_NORMAL_PRIORITY_CLASS: + return 8; + case IDLE_PRIORITY_CLASS: + return 16; + } + return 0; +} + +/* Get a Win32 priority matching the incoming nice factor. The incoming + nice is limited to the interval [-NZERO,NZERO-1]. */ +DWORD +nice_to_winprio (int &nice) +{ + static const DWORD priority[] NO_COPY = + { + REALTIME_PRIORITY_CLASS, /* 0 */ + HIGH_PRIORITY_CLASS, /* 1 */ + HIGH_PRIORITY_CLASS, + HIGH_PRIORITY_CLASS, + HIGH_PRIORITY_CLASS, + HIGH_PRIORITY_CLASS, + HIGH_PRIORITY_CLASS, + HIGH_PRIORITY_CLASS, /* 7 */ + ABOVE_NORMAL_PRIORITY_CLASS, /* 8 */ + ABOVE_NORMAL_PRIORITY_CLASS, + ABOVE_NORMAL_PRIORITY_CLASS, + ABOVE_NORMAL_PRIORITY_CLASS, + ABOVE_NORMAL_PRIORITY_CLASS, + ABOVE_NORMAL_PRIORITY_CLASS, + ABOVE_NORMAL_PRIORITY_CLASS, + ABOVE_NORMAL_PRIORITY_CLASS, /* 15 */ + NORMAL_PRIORITY_CLASS, /* 16 */ + NORMAL_PRIORITY_CLASS, + NORMAL_PRIORITY_CLASS, + NORMAL_PRIORITY_CLASS, + NORMAL_PRIORITY_CLASS, + NORMAL_PRIORITY_CLASS, + NORMAL_PRIORITY_CLASS, + NORMAL_PRIORITY_CLASS, /* 23 */ + BELOW_NORMAL_PRIORITY_CLASS, /* 24 */ + BELOW_NORMAL_PRIORITY_CLASS, + BELOW_NORMAL_PRIORITY_CLASS, + BELOW_NORMAL_PRIORITY_CLASS, + BELOW_NORMAL_PRIORITY_CLASS, + BELOW_NORMAL_PRIORITY_CLASS, + BELOW_NORMAL_PRIORITY_CLASS, + BELOW_NORMAL_PRIORITY_CLASS, /* 31 */ + IDLE_PRIORITY_CLASS, /* 32 */ + IDLE_PRIORITY_CLASS, + IDLE_PRIORITY_CLASS, + IDLE_PRIORITY_CLASS, + IDLE_PRIORITY_CLASS, + IDLE_PRIORITY_CLASS, + IDLE_PRIORITY_CLASS, + IDLE_PRIORITY_CLASS /* 39 */ + }; + if (nice < -NZERO) + nice = -NZERO; + else if (nice > NZERO - 1) + nice = NZERO - 1; + DWORD prio = priority[nice + NZERO]; + if (!wincap.has_extended_priority_class () + && (prio == BELOW_NORMAL_PRIORITY_CLASS + || prio == ABOVE_NORMAL_PRIORITY_CLASS)) + prio = NORMAL_PRIORITY_CLASS; + return prio; +} diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 754fd75a0..76e52d5b2 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -98,6 +98,8 @@ pinfo_init (char **envp, int envc) myself->uid = ILLEGAL_UID; myself->gid = UNKNOWN_GID; environ_init (NULL, 0); /* call after myself has been set up */ + myself->nice = winprio_to_nice (GetPriorityClass (hMainProc)); + debug_printf ("Set nice to %d", myself->nice); } debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid); diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index d202d91f1..013de17e1 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -75,6 +75,7 @@ public: long start_time; struct rusage rusage_self; struct rusage rusage_children; + int nice; /* Non-zero if process was stopped by a signal. */ char stopsig; diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 68a49f4fe..1f30175da 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -845,6 +845,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, (void) DuplicateHandle (hMainProc, child.shared_handle (), pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS); child->start_time = time (NULL); /* Register child's starting time. */ + child->nice = myself->nice; if (!child.remember (mode == _P_DETACH)) { /* FIXME: Child in strange state now */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 889d0c782..7ea36273b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2443,48 +2443,43 @@ memccpy (_PTR out, const _PTR in, int c, size_t len) } extern "C" int -nice (int incr) +setpriority (int which, id_t who, int value) { - DWORD priority[] = + /* TODO: Support PRIO_PGRP and PRIO_USER. */ + if (which != PRIO_PROCESS || (who != 0 && (pid_t) who != myself->pid)) { - IDLE_PRIORITY_CLASS, - IDLE_PRIORITY_CLASS, - NORMAL_PRIORITY_CLASS, - HIGH_PRIORITY_CLASS, - REALTIME_PRIORITY_CLASS, - REALTIME_PRIORITY_CLASS - }; - int curr = 2; - - switch (GetPriorityClass (hMainProc)) - { - case IDLE_PRIORITY_CLASS: - curr = 1; - break; - case NORMAL_PRIORITY_CLASS: - curr = 2; - break; - case HIGH_PRIORITY_CLASS: - curr = 3; - break; - case REALTIME_PRIORITY_CLASS: - curr = 4; - break; + set_errno (EINVAL); + return -1; } - if (incr > 0) - incr = -1; - else if (incr < 0) - incr = 1; - - if (SetPriorityClass (hMainProc, priority[curr + incr]) == FALSE) + DWORD prio = nice_to_winprio (value); + if (SetPriorityClass (hMainProc, prio) == FALSE) { __seterrno (); return -1; } - + myself->nice = value; + debug_printf ("Set nice to %d", myself->nice); return 0; } +extern "C" int +getpriority (int which, id_t who) +{ + /* TODO: Support PRIO_PGRP and PRIO_USER. */ + if (which != PRIO_PROCESS || (who != 0 && (pid_t) who != myself->pid)) + { + set_errno (EINVAL); + return -1; + } + return myself->nice; +} + +extern "C" int +nice (int incr) +{ + return setpriority (PRIO_PROCESS, myself->pid, myself->nice + incr); +} + /* * Find the first bit set in I. */ @@ -2588,7 +2583,7 @@ endutent () } extern "C" void -utmpname (_CONST char *file) +utmpname (const char *file) { if (check_null_empty_str (file)) { diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index eb4981225..dee7ed9c1 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -54,7 +54,8 @@ static NO_COPY wincaps wincap_unknown = { has_switch_to_thread:false, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:true + start_proc_suspended:true, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_95 = { @@ -100,7 +101,8 @@ static NO_COPY wincaps wincap_95 = { has_switch_to_thread:false, cant_debug_dll_entry:true, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:true + start_proc_suspended:true, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_95osr2 = { @@ -146,7 +148,8 @@ static NO_COPY wincaps wincap_95osr2 = { has_switch_to_thread:false, cant_debug_dll_entry:true, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:true + start_proc_suspended:true, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_98 = { @@ -192,7 +195,8 @@ static NO_COPY wincaps wincap_98 = { has_switch_to_thread:false, cant_debug_dll_entry:true, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:true + start_proc_suspended:true, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_98se = { @@ -238,7 +242,8 @@ static NO_COPY wincaps wincap_98se = { has_switch_to_thread:false, cant_debug_dll_entry:true, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:true + start_proc_suspended:true, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_me = { @@ -284,7 +289,8 @@ static NO_COPY wincaps wincap_me = { has_switch_to_thread:false, cant_debug_dll_entry:true, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:true + start_proc_suspended:true, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_nt3 = { @@ -330,7 +336,8 @@ static NO_COPY wincaps wincap_nt3 = { has_switch_to_thread:false, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:false + start_proc_suspended:false, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_nt4 = { @@ -376,7 +383,8 @@ static NO_COPY wincaps wincap_nt4 = { has_switch_to_thread:true, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:false + start_proc_suspended:false, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_nt4sp4 = { @@ -422,7 +430,8 @@ static NO_COPY wincaps wincap_nt4sp4 = { has_switch_to_thread:true, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:false + start_proc_suspended:false, + has_extended_priority_class:false }; static NO_COPY wincaps wincap_2000 = { @@ -468,7 +477,8 @@ static NO_COPY wincaps wincap_2000 = { has_switch_to_thread:true, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:false, - start_proc_suspended:false + start_proc_suspended:false, + has_extended_priority_class:true }; static NO_COPY wincaps wincap_xp = { @@ -514,7 +524,8 @@ static NO_COPY wincaps wincap_xp = { has_switch_to_thread:true, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:true, - start_proc_suspended:false + start_proc_suspended:false, + has_extended_priority_class:true }; static NO_COPY wincaps wincap_2003 = { @@ -560,7 +571,8 @@ static NO_COPY wincaps wincap_2003 = { has_switch_to_thread:true, cant_debug_dll_entry:false, has_ioctl_storage_get_media_types_ex:true, - start_proc_suspended:false + start_proc_suspended:false, + has_extended_priority_class:true }; wincapc wincap; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index eb9c5ba3f..020285f85 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -56,6 +56,7 @@ struct wincaps unsigned cant_debug_dll_entry : 1; unsigned has_ioctl_storage_get_media_types_ex : 1; unsigned start_proc_suspended : 1; + unsigned has_extended_priority_class : 1; }; class wincapc @@ -116,6 +117,7 @@ public: bool IMPLEMENT (cant_debug_dll_entry) bool IMPLEMENT (has_ioctl_storage_get_media_types_ex) bool IMPLEMENT (start_proc_suspended) + bool IMPLEMENT (has_extended_priority_class) #undef IMPLEMENT }; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index bee5fa2ec..9be8d679d 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -306,6 +306,9 @@ extern "C" int low_priority_sleep (DWORD) __attribute__ ((regparm (1))); size_t getshmlba (void); +int winprio_to_nice (DWORD) __attribute__ ((regparm (1))); +DWORD nice_to_winprio (int &) __attribute__ ((regparm (1))); + /**************************** Exports ******************************/ extern "C" {