* 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>
* miscfuncs.cc (thread_wrapper): Remove unused _cygtls record.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 **);

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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);

View File

@ -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;
}