* 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.
This commit is contained in:
parent
5e3af166d7
commit
c8ce54290d
|
@ -1,3 +1,31 @@
|
|||
2011-05-17 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||
|
||||
* 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.
|
||||
|
||||
2011-05-17 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* miscfuncs.cc (thread_wrapper): Remove unused _cygtls record.
|
||||
|
|
|
@ -217,6 +217,7 @@ clearerr SIGFE
|
|||
_clearerr = clearerr SIGFE
|
||||
clock SIGFE
|
||||
_clock = clock SIGFE
|
||||
clock_getcpuclockid SIGFE
|
||||
clock_getres SIGFE
|
||||
clock_gettime SIGFE
|
||||
clock_setres SIGFE
|
||||
|
@ -1212,6 +1213,7 @@ pthread_equal SIGFE
|
|||
pthread_exit SIGFE
|
||||
pthread_getattr_np SIGFE
|
||||
pthread_getconcurrency SIGFE
|
||||
pthread_getcpuclockid SIGFE
|
||||
pthread_getschedparam SIGFE
|
||||
pthread_getsequence_np SIGFE
|
||||
pthread_getspecific SIGFE
|
||||
|
|
|
@ -13,6 +13,14 @@ details. */
|
|||
|
||||
#include <mmsystem.h>
|
||||
|
||||
/* Conversions for per-process and per-thread clocks */
|
||||
#define PID_TO_CLOCKID(pid) (pid * 8 + CLOCK_PROCESS_CPUTIME_ID)
|
||||
#define CLOCKID_TO_PID(cid) ((cid - CLOCK_PROCESS_CPUTIME_ID) / 8)
|
||||
#define CLOCKID_IS_PROCESS(cid) ((cid % 8) == CLOCK_PROCESS_CPUTIME_ID)
|
||||
#define THREADID_TO_CLOCKID(tid) (tid * 8 + CLOCK_THREAD_CPUTIME_ID)
|
||||
#define CLOCKID_TO_THREADID(cid) ((cid - CLOCK_THREAD_CPUTIME_ID) / 8)
|
||||
#define CLOCKID_IS_THREAD(cid) ((cid % 8) == CLOCK_THREAD_CPUTIME_ID)
|
||||
|
||||
/* Largest delay in ms for sleep and alarm calls.
|
||||
Allow actual delay to exceed requested delay by 10 s.
|
||||
Express as multiple of 1000 (i.e. seconds) + max resolution
|
||||
|
|
|
@ -412,12 +412,14 @@ details. */
|
|||
244: Export clock_settime.
|
||||
245: Export pthread_attr_getguardsize, pthread_attr_setguardsize,
|
||||
pthread_attr_setstack, pthread_attr_setstackaddr.
|
||||
246: Add CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID.
|
||||
Export clock_getcpuclockid, pthread_getcpuclockid.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 245
|
||||
#define CYGWIN_VERSION_API_MINOR 246
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -141,6 +141,7 @@ int pthread_create (pthread_t *, const pthread_attr_t *,
|
|||
int pthread_detach (pthread_t);
|
||||
int pthread_equal (pthread_t, pthread_t);
|
||||
void pthread_exit (void *);
|
||||
int pthread_getcpuclockid (pthread_t, clockid_t *);
|
||||
int pthread_getschedparam (pthread_t, int *, struct sched_param *);
|
||||
void *pthread_getspecific (pthread_key_t);
|
||||
int pthread_join (pthread_t, void **);
|
||||
|
|
|
@ -938,6 +938,7 @@ typedef enum _EVENT_INFORMATION_CLASS
|
|||
typedef enum _THREAD_INFORMATION_CLASS
|
||||
{
|
||||
ThreadBasicInformation = 0,
|
||||
ThreadTimes = 1,
|
||||
ThreadImpersonationToken = 5
|
||||
} THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;
|
||||
|
||||
|
|
|
@ -90,8 +90,9 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
cimagf
|
||||
clearerr
|
||||
clock
|
||||
clock_getres (see chapter "Implementation Notes")
|
||||
clock_gettime (see chapter "Implementation Notes")
|
||||
clock_getcpuclockid
|
||||
clock_getres
|
||||
clock_gettime
|
||||
clock_settime (see chapter "Implementation Notes")
|
||||
clog
|
||||
clogf
|
||||
|
@ -564,6 +565,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
pthread_equal
|
||||
pthread_exit
|
||||
pthread_getconcurrency
|
||||
pthread_getcpuclockid
|
||||
pthread_getschedparam
|
||||
pthread_getspecific
|
||||
pthread_join
|
||||
|
@ -836,7 +838,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
tgamma
|
||||
tgammaf
|
||||
time
|
||||
timer_create
|
||||
timer_create (see chapter "Implementation Notes")
|
||||
timer_delete
|
||||
timer_gettime
|
||||
timer_settime
|
||||
|
@ -1292,7 +1294,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
ceill
|
||||
cexpl
|
||||
cimagl
|
||||
clock_getcpuclockid
|
||||
clogl
|
||||
conjl
|
||||
copysignl
|
||||
|
@ -1386,7 +1387,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
pthread_barrier[...]
|
||||
pthread_condattr_getclock
|
||||
pthread_condattr_setclock
|
||||
pthread_getcpuclockid
|
||||
pthread_mutexattr_getrobust
|
||||
pthread_mutexattr_setrobust
|
||||
pthread_mutex_consistent
|
||||
|
@ -1441,9 +1441,8 @@ by keeping track of the current root and accomodating this in the file
|
|||
related function calls. A real chroot functionality is not supported by
|
||||
Windows however.</para>
|
||||
|
||||
<para><function>clock_getres</function> and <function>clock_gettime</function>
|
||||
only support CLOCK_REALTIME and CLOCK_MONOTONIC for now. <function>clock_setres</function>
|
||||
and <function>clock_settime</function> only support CLOCK_REALTIME.</para>
|
||||
<function>clock_setres</function>, <function>clock_settime</function>, and
|
||||
<function>timer_create</function> only support CLOCK_REALTIME.</para>
|
||||
|
||||
<para>BSD file locks created via <function>flock</function> are not
|
||||
propagated to the parent process and sibling processes. The locks are
|
||||
|
|
|
@ -160,7 +160,7 @@ static struct
|
|||
{cons, {c:BC_STRING_MAX}}, /* 60, _SC_BC_STRING_MAX */
|
||||
{cons, {c:-1L}}, /* 61, _SC_CLOCK_SELECTION */
|
||||
{nsup, {c:0}}, /* 62, _SC_COLL_WEIGHTS_MAX */
|
||||
{cons, {c:-1L}}, /* 63, _SC_CPUTIME */
|
||||
{cons, {c:_POSIX_CPUTIME}}, /* 63, _SC_CPUTIME */
|
||||
{cons, {c:EXPR_NEST_MAX}}, /* 64, _SC_EXPR_NEST_MAX */
|
||||
{cons, {c:HOST_NAME_MAX}}, /* 65, _SC_HOST_NAME_MAX */
|
||||
{cons, {c:IOV_MAX}}, /* 66, _SC_IOV_MAX */
|
||||
|
@ -177,7 +177,7 @@ static struct
|
|||
{cons, {c:-1L}}, /* 77, _SC_SPORADIC_SERVER */
|
||||
{nsup, {c:0}}, /* 78, _SC_SS_REPL_MAX */
|
||||
{cons, {c:SYMLOOP_MAX}}, /* 79, _SC_SYMLOOP_MAX */
|
||||
{cons, {c:-1L}}, /* 80, _SC_THREAD_CPUTIME */
|
||||
{cons, {c:_POSIX_THREAD_CPUTIME}}, /* 80, _SC_THREAD_CPUTIME */
|
||||
{cons, {c:-1L}}, /* 81, _SC_THREAD_SPORADIC_SERVER */
|
||||
{cons, {c:-1L}}, /* 82, _SC_TIMEOUTS */
|
||||
{cons, {c:-1L}}, /* 83, _SC_TRACE */
|
||||
|
|
|
@ -2510,6 +2510,15 @@ pthread_getconcurrency ()
|
|||
return MT_INTERFACE->concurrency;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
pthread_getcpuclockid (pthread_t thread, clockid_t *clk_id)
|
||||
{
|
||||
if (!pthread::is_good_object (&thread))
|
||||
return (ESRCH);
|
||||
*clk_id = (clockid_t) THREADID_TO_CLOCKID (thread->getsequence_np ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* keep this in sync with sched.cc */
|
||||
extern "C" int
|
||||
pthread_getschedparam (pthread_t thread, int *policy,
|
||||
|
|
|
@ -300,6 +300,13 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
|
|||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (clock_id != CLOCK_REALTIME)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue