* 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:
Yaakov Selkowitz 2011-05-17 17:08:10 +00:00
parent 5e3af166d7
commit c8ce54290d
11 changed files with 156 additions and 11 deletions

View File

@ -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> 2011-05-17 Corinna Vinschen <corinna@vinschen.de>
* miscfuncs.cc (thread_wrapper): Remove unused _cygtls record. * miscfuncs.cc (thread_wrapper): Remove unused _cygtls record.

View File

@ -217,6 +217,7 @@ clearerr SIGFE
_clearerr = clearerr SIGFE _clearerr = clearerr SIGFE
clock SIGFE clock SIGFE
_clock = clock SIGFE _clock = clock SIGFE
clock_getcpuclockid SIGFE
clock_getres SIGFE clock_getres SIGFE
clock_gettime SIGFE clock_gettime SIGFE
clock_setres SIGFE clock_setres SIGFE
@ -1212,6 +1213,7 @@ pthread_equal SIGFE
pthread_exit SIGFE pthread_exit SIGFE
pthread_getattr_np SIGFE pthread_getattr_np SIGFE
pthread_getconcurrency SIGFE pthread_getconcurrency SIGFE
pthread_getcpuclockid SIGFE
pthread_getschedparam SIGFE pthread_getschedparam SIGFE
pthread_getsequence_np SIGFE pthread_getsequence_np SIGFE
pthread_getspecific SIGFE pthread_getspecific SIGFE

View File

@ -13,6 +13,14 @@ details. */
#include <mmsystem.h> #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. /* Largest delay in ms for sleep and alarm calls.
Allow actual delay to exceed requested delay by 10 s. Allow actual delay to exceed requested delay by 10 s.
Express as multiple of 1000 (i.e. seconds) + max resolution Express as multiple of 1000 (i.e. seconds) + max resolution

View File

@ -412,12 +412,14 @@ details. */
244: Export clock_settime. 244: Export clock_settime.
245: Export pthread_attr_getguardsize, pthread_attr_setguardsize, 245: Export pthread_attr_getguardsize, pthread_attr_setguardsize,
pthread_attr_setstack, pthread_attr_setstackaddr. 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 */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #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 /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -141,6 +141,7 @@ int pthread_create (pthread_t *, const pthread_attr_t *,
int pthread_detach (pthread_t); int pthread_detach (pthread_t);
int pthread_equal (pthread_t, pthread_t); int pthread_equal (pthread_t, pthread_t);
void pthread_exit (void *); void pthread_exit (void *);
int pthread_getcpuclockid (pthread_t, clockid_t *);
int pthread_getschedparam (pthread_t, int *, struct sched_param *); int pthread_getschedparam (pthread_t, int *, struct sched_param *);
void *pthread_getspecific (pthread_key_t); void *pthread_getspecific (pthread_key_t);
int pthread_join (pthread_t, void **); int pthread_join (pthread_t, void **);

View File

@ -938,6 +938,7 @@ typedef enum _EVENT_INFORMATION_CLASS
typedef enum _THREAD_INFORMATION_CLASS typedef enum _THREAD_INFORMATION_CLASS
{ {
ThreadBasicInformation = 0, ThreadBasicInformation = 0,
ThreadTimes = 1,
ThreadImpersonationToken = 5 ThreadImpersonationToken = 5
} THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS; } THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;

View File

@ -90,8 +90,9 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
cimagf cimagf
clearerr clearerr
clock clock
clock_getres (see chapter "Implementation Notes") clock_getcpuclockid
clock_gettime (see chapter "Implementation Notes") clock_getres
clock_gettime
clock_settime (see chapter "Implementation Notes") clock_settime (see chapter "Implementation Notes")
clog clog
clogf clogf
@ -564,6 +565,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
pthread_equal pthread_equal
pthread_exit pthread_exit
pthread_getconcurrency pthread_getconcurrency
pthread_getcpuclockid
pthread_getschedparam pthread_getschedparam
pthread_getspecific pthread_getspecific
pthread_join pthread_join
@ -836,7 +838,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
tgamma tgamma
tgammaf tgammaf
time time
timer_create timer_create (see chapter "Implementation Notes")
timer_delete timer_delete
timer_gettime timer_gettime
timer_settime timer_settime
@ -1292,7 +1294,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
ceill ceill
cexpl cexpl
cimagl cimagl
clock_getcpuclockid
clogl clogl
conjl conjl
copysignl copysignl
@ -1386,7 +1387,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
pthread_barrier[...] pthread_barrier[...]
pthread_condattr_getclock pthread_condattr_getclock
pthread_condattr_setclock pthread_condattr_setclock
pthread_getcpuclockid
pthread_mutexattr_getrobust pthread_mutexattr_getrobust
pthread_mutexattr_setrobust pthread_mutexattr_setrobust
pthread_mutex_consistent 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 related function calls. A real chroot functionality is not supported by
Windows however.</para> Windows however.</para>
<para><function>clock_getres</function> and <function>clock_gettime</function> <function>clock_setres</function>, <function>clock_settime</function>, and
only support CLOCK_REALTIME and CLOCK_MONOTONIC for now. <function>clock_setres</function> <function>timer_create</function> only support CLOCK_REALTIME.</para>
and <function>clock_settime</function> only support CLOCK_REALTIME.</para>
<para>BSD file locks created via <function>flock</function> are not <para>BSD file locks created via <function>flock</function> are not
propagated to the parent process and sibling processes. The locks are propagated to the parent process and sibling processes. The locks are

View File

@ -160,7 +160,7 @@ static struct
{cons, {c:BC_STRING_MAX}}, /* 60, _SC_BC_STRING_MAX */ {cons, {c:BC_STRING_MAX}}, /* 60, _SC_BC_STRING_MAX */
{cons, {c:-1L}}, /* 61, _SC_CLOCK_SELECTION */ {cons, {c:-1L}}, /* 61, _SC_CLOCK_SELECTION */
{nsup, {c:0}}, /* 62, _SC_COLL_WEIGHTS_MAX */ {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:EXPR_NEST_MAX}}, /* 64, _SC_EXPR_NEST_MAX */
{cons, {c:HOST_NAME_MAX}}, /* 65, _SC_HOST_NAME_MAX */ {cons, {c:HOST_NAME_MAX}}, /* 65, _SC_HOST_NAME_MAX */
{cons, {c:IOV_MAX}}, /* 66, _SC_IOV_MAX */ {cons, {c:IOV_MAX}}, /* 66, _SC_IOV_MAX */
@ -177,7 +177,7 @@ static struct
{cons, {c:-1L}}, /* 77, _SC_SPORADIC_SERVER */ {cons, {c:-1L}}, /* 77, _SC_SPORADIC_SERVER */
{nsup, {c:0}}, /* 78, _SC_SS_REPL_MAX */ {nsup, {c:0}}, /* 78, _SC_SS_REPL_MAX */
{cons, {c:SYMLOOP_MAX}}, /* 79, _SC_SYMLOOP_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}}, /* 81, _SC_THREAD_SPORADIC_SERVER */
{cons, {c:-1L}}, /* 82, _SC_TIMEOUTS */ {cons, {c:-1L}}, /* 82, _SC_TIMEOUTS */
{cons, {c:-1L}}, /* 83, _SC_TRACE */ {cons, {c:-1L}}, /* 83, _SC_TRACE */

View File

@ -2510,6 +2510,15 @@ pthread_getconcurrency ()
return MT_INTERFACE->concurrency; 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 */ /* keep this in sync with sched.cc */
extern "C" int extern "C" int
pthread_getschedparam (pthread_t thread, int *policy, pthread_getschedparam (pthread_t thread, int *policy,

View File

@ -300,6 +300,13 @@ timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
myfault efault; myfault efault;
if (efault.faulted (EFAULT)) if (efault.faulted (EFAULT))
return -1; return -1;
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
{
set_errno (ENOTSUP);
return -1;
}
if (clock_id != CLOCK_REALTIME) if (clock_id != CLOCK_REALTIME)
{ {
set_errno (EINVAL); set_errno (EINVAL);

View File

@ -15,6 +15,7 @@ details. */
#include <sys/timeb.h> #include <sys/timeb.h>
#include <utime.h> #include <utime.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "cygerrno.h" #include "cygerrno.h"
#include "security.h" #include "security.h"
#include "path.h" #include "path.h"
@ -22,6 +23,7 @@ details. */
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "pinfo.h" #include "pinfo.h"
#include "thread.h"
#include "cygtls.h" #include "cygtls.h"
#include "ntdll.h" #include "ntdll.h"
@ -594,6 +596,63 @@ hires_ms::nsecs ()
extern "C" int extern "C" int
clock_gettime (clockid_t clk_id, struct timespec *tp) 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) switch (clk_id)
{ {
case CLOCK_REALTIME: case CLOCK_REALTIME:
@ -630,6 +689,16 @@ clock_settime (clockid_t clk_id, const struct timespec *tp)
{ {
struct timeval tv; 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) if (clk_id != CLOCK_REALTIME)
{ {
set_errno (EINVAL); set_errno (EINVAL);
@ -702,6 +771,16 @@ hires_ms::resolution ()
extern "C" int extern "C" int
clock_getres (clockid_t clk_id, struct timespec *tp) 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) switch (clk_id)
{ {
case CLOCK_REALTIME: case CLOCK_REALTIME:
@ -776,3 +855,12 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
period_set = true; period_set = true;
return 0; 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;
}