diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5b1306d75..0663b831d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,24 @@ +2003-09-26 Vaclav Haisman + + * Makefile.in: Add libusr32.a to DLL_IMPORTS. + * wincap.h (wincaps::is_server): New flag. + (wincapc::version): Change type to OSVERSIONINFOEX. + (wincapc::is_server): New function. + * wincap.cc (wincap_unknown::is_server): New initializer. + (wincap_95): Ditto. + (wincap_95osr2): Ditto. + (wincap_98): Ditto. + (wincap_me): Ditto. + (wincap_nt3): Ditto. + (wincap_nt4): Ditto. + (wincap_nt4sp4): Ditto. + (wincap_2000): Ditto. + (wincap_xp): Ditto. + (wincapc::init): Adapt to OSVERSIONINFOEX. Add detection of NT server + systems. + * sched.cc: Include windows.h and registry.h. + (sched_rr_get_interval): Re-implement for NT systems. + 2003-09-26 Christopher Faylor * fhandler_tty.cc (fhandler_tty_slave::ioctl): Properly set diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 9c1bb4731..1628480f8 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -415,11 +415,13 @@ LoadDLLfunc (DispatchMessageA, 4, user32) LoadDLLfunc (EmptyClipboard, 0, user32) LoadDLLfunc (FindWindowA, 8, user32) LoadDLLfunc (GetClipboardData, 4, user32) +LoadDLLfunc (GetForegroundWindow, 0, user32) LoadDLLfunc (GetKeyboardLayout, 4, user32) LoadDLLfunc (GetMessageA, 16, user32) LoadDLLfunc (GetPriorityClipboardFormat, 8, user32) LoadDLLfunc (GetProcessWindowStation, 0, user32) LoadDLLfunc (GetThreadDesktop, 4, user32) +LoadDLLfunc (GetWindowThreadProcessId, 8, user32) LoadDLLfunc (GetUserObjectInformationA, 20, user32) LoadDLLfunc (KillTimer, 8, user32) LoadDLLfunc (MessageBeep, 4, user32) diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc index b29d7a49e..548c65957 100644 --- a/winsup/cygwin/sched.cc +++ b/winsup/cygwin/sched.cc @@ -14,6 +14,7 @@ # include "config.h" #endif +#define _WIN32_WINNT 0x300 #include "winsup.h" #include #include "cygerrno.h" @@ -24,6 +25,9 @@ #include "pinfo.h" /* for getpid */ #include +#include "registry.h" + +extern "C" HWND WINAPI GetForegroundWindow(); /* Win32 priority to UNIX priority Mapping. For now, I'm just following the spec: any range of priorities is ok. @@ -249,21 +253,75 @@ sched_getscheduler (pid_t pid) /* get the time quantum for pid - We can't return -11, errno ENOSYS, because that implies that - sched_get_priority_max & min are also not supported (according to the spec) - so some spec-driven autoconf tests will likely assume they aren't present either - - returning ESRCH might confuse some applications (if they assumed that when - rr_get_interval is called on pid 0 it always works). - - If someone knows the time quanta for the various win32 platforms, then a - simple check for the os we're running on will finish this function + Implemented only for NT systems, it fails and sets errno to ESRCH + for non-NT systems. */ int sched_rr_get_interval (pid_t pid, struct timespec *interval) { - set_errno (ESRCH); - return -1; + static const char quantable[2][2][3] = + {{{12, 24, 36}, { 6, 12, 18}}, + {{36, 36, 36}, {18, 18, 18}}}; + /* FIXME: Clocktickinterval can be 15 ms for multi-processor system. */ + static const int clocktickinterval = 10; + static const int quantapertick = 3; + + HWND forwin; + DWORD forprocid; + int vfindex, slindex, qindex, prisep; + long nsec; + + if (!wincap.is_winnt ()) + { + set_errno (ESRCH); + return -1; + } + + forwin = GetForegroundWindow (); + if (!forwin) + GetWindowThreadProcessId (forwin, &forprocid); + else + forprocid = 0; + + reg_key reg (HKEY_LOCAL_MACHINE, KEY_READ, "SYSTEM", "CurrentControlSet", + "Control", "PriorityControl", NULL); + if (reg.error ()) + { + set_errno (ESRCH); + return -1; + } + prisep = reg.get_int ("Win32PrioritySeparation", 2); + pinfo pi (pid ? pid : myself->pid); + if (!pi) + { + set_errno (ESRCH); + return -1; + } + + if (pi->dwProcessId == forprocid) + { + qindex = prisep & 3; + qindex = qindex == 3 ? 2 : qindex; + } + else + qindex = 0; + vfindex = ((prisep >> 2) & 3) % 3; + if (vfindex == 0) + vfindex = wincap.is_server () || prisep & 3 == 0 ? 1 : 0; + else + vfindex -= 1; + slindex = ((prisep >> 4) & 3) % 3; + if (slindex == 0) + slindex = wincap.is_server () ? 1 : 0; + else + slindex -= 1; + + nsec = quantable[vfindex][slindex][qindex] / quantapertick + * clocktickinterval * 1000000; + interval->tv_sec = nsec / 1000000000; + interval->tv_nsec = nsec % 1000000000; + + return 0; } /* set the scheduling parameters */ diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 33676ee6f..0f69abee9 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -16,6 +16,7 @@ static NO_COPY wincaps wincap_unknown = { chunksize:0x0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE, is_winnt:false, + is_server:false, access_denied_on_delete:false, has_delete_on_close:false, has_page_guard:false, @@ -58,6 +59,7 @@ static NO_COPY wincaps wincap_95 = { chunksize:32 * 1024 * 1024, shared:FILE_SHARE_READ | FILE_SHARE_WRITE, is_winnt:false, + is_server:false, access_denied_on_delete:true, has_delete_on_close:false, has_page_guard:false, @@ -100,6 +102,7 @@ static NO_COPY wincaps wincap_95osr2 = { chunksize:32 * 1024 * 1024, shared:FILE_SHARE_READ | FILE_SHARE_WRITE, is_winnt:false, + is_server:false, access_denied_on_delete:true, has_delete_on_close:false, has_page_guard:false, @@ -142,6 +145,7 @@ static NO_COPY wincaps wincap_98 = { chunksize:32 * 1024 * 1024, shared:FILE_SHARE_READ | FILE_SHARE_WRITE, is_winnt:false, + is_server:false, access_denied_on_delete:true, has_delete_on_close:false, has_page_guard:false, @@ -184,6 +188,7 @@ static NO_COPY wincaps wincap_98se = { chunksize:32 * 1024 * 1024, shared:FILE_SHARE_READ | FILE_SHARE_WRITE, is_winnt:false, + is_server:false, access_denied_on_delete:true, has_delete_on_close:false, has_page_guard:false, @@ -226,6 +231,7 @@ static NO_COPY wincaps wincap_me = { chunksize:32 * 1024 * 1024, shared:FILE_SHARE_READ | FILE_SHARE_WRITE, is_winnt:false, + is_server:false, access_denied_on_delete:true, has_delete_on_close:false, has_page_guard:false, @@ -268,6 +274,7 @@ static NO_COPY wincaps wincap_nt3 = { chunksize:0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, is_winnt:true, + is_server:false, access_denied_on_delete:false, has_delete_on_close:true, has_page_guard:true, @@ -310,6 +317,7 @@ static NO_COPY wincaps wincap_nt4 = { chunksize:0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, is_winnt:true, + is_server:false, access_denied_on_delete:false, has_delete_on_close:true, has_page_guard:true, @@ -352,6 +360,7 @@ static NO_COPY wincaps wincap_nt4sp4 = { chunksize:0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, is_winnt:true, + is_server:false, access_denied_on_delete:false, has_delete_on_close:true, has_page_guard:true, @@ -394,6 +403,7 @@ static NO_COPY wincaps wincap_2000 = { chunksize:0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, is_winnt:true, + is_server:false, access_denied_on_delete:false, has_delete_on_close:true, has_page_guard:true, @@ -436,6 +446,7 @@ static NO_COPY wincaps wincap_xp = { chunksize:0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, is_winnt:true, + is_server:false, access_denied_on_delete:false, has_delete_on_close:true, has_page_guard:true, @@ -478,6 +489,7 @@ static NO_COPY wincaps wincap_2003 = { chunksize:0, shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, is_winnt:true, + is_server:true, access_denied_on_delete:false, has_delete_on_close:true, has_page_guard:true, @@ -526,8 +538,8 @@ wincapc::init () return; // already initialized memset (&version, 0, sizeof version); - version.dwOSVersionInfoSize = sizeof version; - GetVersionEx (&version); + version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + GetVersionEx (reinterpret_cast (&version)); switch (version.dwPlatformId) { @@ -599,6 +611,15 @@ wincapc::init () caps = &wincap_unknown; break; } + + if (((wincaps *)this->caps)->is_winnt && version.dwMajorVersion > 4) + { + version.dwOSVersionInfoSize = sizeof version; + GetVersionEx (reinterpret_cast(&version)); + if (version.wProductType != VER_NT_WORKSTATION) + ((wincaps *)this->caps)->is_server = true; + } + __small_sprintf (osnam, "%s-%d.%d", os, version.dwMajorVersion, version.dwMinorVersion); } diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index faf246906..320b75916 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -17,6 +17,7 @@ struct wincaps DWORD chunksize; int shared; unsigned is_winnt : 1; + unsigned is_server : 1; unsigned access_denied_on_delete : 1; unsigned has_delete_on_close : 1; unsigned has_page_guard : 1; @@ -56,9 +57,9 @@ struct wincaps class wincapc { - OSVERSIONINFO version; - char osnam[40]; - void *caps; + OSVERSIONINFOEX version; + char osnam[40]; + void *caps; public: void init (); @@ -67,12 +68,13 @@ public: const char *osname () const { return osnam; } -#define IMPLEMENT(cap) cap() const { return ((wincaps *)this->caps)->cap; } +#define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; } DWORD IMPLEMENT (lock_file_highword) DWORD IMPLEMENT (chunksize) int IMPLEMENT (shared) bool IMPLEMENT (is_winnt) + bool IMPLEMENT (is_server) bool IMPLEMENT (access_denied_on_delete) bool IMPLEMENT (has_delete_on_close) bool IMPLEMENT (has_page_guard)