Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaakov Selkowitz <yselkowi@redhat.com>2011-05-17 21:08:10 +0400
committerYaakov Selkowitz <yselkowi@redhat.com>2011-05-17 21:08:10 +0400
commitc8ce54290ddec2e84ac94bef53c518c43140c183 (patch)
tree3aedcb9955b2a790c5a39a722dd1145cd8b8a550 /winsup/cygwin/times.cc
parent5e3af166d7f81d96adb225f6511d08e70bb2610d (diff)
* cygwin.din (clock_getcpuclockid): Export.
(pthread_getcpuclockid): Export. * hires.h (PID_TO_CLOCKID): New macro. (CLOCKID_TO_PID): New macro. (CLOCKID_IS_PROCESS): New macro. (THREADID_TO_CLOCKID): New macro. (CLOCKID_TO_THREADID): New macro. (CLOCKID_IS_THREAD): New macro. * ntdll.h (enum _THREAD_INFORMATION_CLASS): Add ThreadTimes. * posix.sgml (std-notimpl): Add clock_getcpuclockid and pthread_getcpuclockid from here... (std-susv4): ... to here. (std-notes): Remove limitations of clock_getres and clock_gettime. Note limitation of timer_create to CLOCK_REALTIME. * sysconf.cc (sca): Set _SC_CPUTIME to _POSIX_CPUTIME, and _SC_THREAD_CPUTIME to _POSIX_THREAD_CPUTIME. * thread.cc (pthread_getcpuclockid): New function. * timer.cc (timer_create): Set errno to ENOTSUP for CPU-time clocks. * times.cc (clock_gettime): Handle CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. (clock_getres): Ditto. (clock_settime): Set errno to EPERM for CPU-time clocks. (clock_getcpuclockid): New function. * include/pthread.h (pthread_getcpuclockid): Declare. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
Diffstat (limited to 'winsup/cygwin/times.cc')
-rw-r--r--winsup/cygwin/times.cc88
1 files changed, 88 insertions, 0 deletions
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index 4e6697e76..6bb68ecd1 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -15,6 +15,7 @@ details. */
#include <sys/timeb.h>
#include <utime.h>
#include <stdlib.h>
+#include <unistd.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
@@ -22,6 +23,7 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "pinfo.h"
+#include "thread.h"
#include "cygtls.h"
#include "ntdll.h"
@@ -594,6 +596,63 @@ hires_ms::nsecs ()
extern "C" int
clock_gettime (clockid_t clk_id, struct timespec *tp)
{
+ if (CLOCKID_IS_PROCESS (clk_id))
+ {
+ pid_t pid = CLOCKID_TO_PID (clk_id);
+ HANDLE hProcess;
+ KERNEL_USER_TIMES kut;
+ ULONG sizeof_kut = sizeof (KERNEL_USER_TIMES);
+ long long x;
+
+ if (pid == 0)
+ pid = getpid ();
+
+ pinfo p (pid);
+ if (!p->exists ())
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, 0, p->dwProcessId);
+ NtQueryInformationProcess (hProcess, ProcessTimes, &kut, sizeof_kut, &sizeof_kut);
+
+ x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart;
+ tp->tv_sec = x / (long long) NSPERSEC;
+ tp->tv_nsec = (x % (long long) NSPERSEC) * 100LL;
+
+ CloseHandle (hProcess);
+ return 0;
+ }
+
+ if (CLOCKID_IS_THREAD (clk_id))
+ {
+ long thr_id = CLOCKID_TO_THREADID (clk_id);
+ HANDLE hThread;
+ KERNEL_USER_TIMES kut;
+ ULONG sizeof_kut = sizeof (KERNEL_USER_TIMES);
+ long long x;
+
+ if (thr_id == 0)
+ thr_id = pthread::self ()->getsequence_np ();
+
+ hThread = OpenThread (THREAD_QUERY_INFORMATION, 0, thr_id);
+ if (!hThread)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ NtQueryInformationThread (hThread, ThreadTimes, &kut, sizeof_kut, &sizeof_kut);
+
+ x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart;
+ tp->tv_sec = x / (long long) NSPERSEC;
+ tp->tv_nsec = (x % (long long) NSPERSEC) * 100LL;
+
+ CloseHandle (hThread);
+ return 0;
+ }
+
switch (clk_id)
{
case CLOCK_REALTIME:
@@ -630,6 +689,16 @@ clock_settime (clockid_t clk_id, const struct timespec *tp)
{
struct timeval tv;
+ if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id))
+ /* According to POSIX, the privileges to set a particular clock
+ * are implementation-defined. On Linux, CPU-time clocks are not
+ * settable; do the same here.
+ */
+ {
+ set_errno (EPERM);
+ return -1;
+ }
+
if (clk_id != CLOCK_REALTIME)
{
set_errno (EINVAL);
@@ -702,6 +771,16 @@ hires_ms::resolution ()
extern "C" int
clock_getres (clockid_t clk_id, struct timespec *tp)
{
+ if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id))
+ {
+ ULONG coarsest, finest, actual;
+
+ NtQueryTimerResolution (&coarsest, &finest, &actual);
+ tp->tv_sec = coarsest / NSPERSEC;
+ tp->tv_nsec = (coarsest % NSPERSEC) * 100;
+ return 0;
+ }
+
switch (clk_id)
{
case CLOCK_REALTIME:
@@ -776,3 +855,12 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
period_set = true;
return 0;
}
+
+extern "C" int
+clock_getcpuclockid (pid_t pid, clockid_t *clk_id)
+{
+ if (pid != 0 && !pinfo (pid)->exists ())
+ return (ESRCH);
+ *clk_id = (clockid_t) PID_TO_CLOCKID (pid);
+ return 0;
+}