* bug#32746: stop using obsolescent setitimer API
@ 2018-09-16 20:19 Paul Eggert
2018-09-17 15:01 ` Eli Zaretskii
0 siblings, 1 reply; 2+ messages in thread
From: Paul Eggert @ 2018-09-16 20:19 UTC (permalink / raw)
To: 32746
[-- Attachment #1: Type: text/plain, Size: 736 bytes --]
POSIX obsoleted the getitimer/setitimer API a decade ago, and now's a good time
for Emacs to stop using this obsolescent API, partly to simplify other timestamp
improvements that I have in mind, partly to head off any other lurking bugs like
the problem I just fixed in commit 238c7cd730819ddba2dbde3c46ee36136575695b
relating to a mistaken assumption about the old API.
Attached please find two proposed patches. The first simplifies Emacs proper to
just use the current timer_gettime/timer_settime API instead (this is the
standard replacement for the obsolescent API). The second patch affects only the
MS-Windows code, modifying it to use the new API instead of the old one; I
haven't tested it as I don't use MS-Windows.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Simplify-by-not-worrying-about-setitimer.patch --]
[-- Type: text/x-patch; name="0001-Simplify-by-not-worrying-about-setitimer.patch", Size: 5156 bytes --]
From 57c9f6a9dfd070fba31da73bfaa14769324be668 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sun, 16 Sep 2018 09:02:15 -0700
Subject: [PATCH 1/2] Simplify by not worrying about setitimer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For a decade, POSIX has recommended that applications use
timer_settime, not the obsolescent setitimer function.
By now support for timer_settime is universal on POSIXish
platforms, so it’s time to drop attempts to use setitimer.
* configure.ac: Do not check for setitimer.
* src/atimer.c (start_atimer, set_alarm)
(debug_timer_callback):
* src/profiler.c (setup_cpu_timer, Fprofiler_cpu_stop):
* src/syssignal.h (PROFILER_CPU_SUPPORT):
Simplify by not worrying about setitimer.
* src/profiler.c (SETITIMER_RUNNING): Remove. All uses removed.
---
admin/CPP-DEFINES | 1 -
configure.ac | 2 +-
src/atimer.c | 15 ++-------------
src/profiler.c | 20 +-------------------
src/syssignal.h | 3 +--
5 files changed, 5 insertions(+), 36 deletions(-)
diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES
index 04d1ff76f3..86a9a3c820 100644
--- a/admin/CPP-DEFINES
+++ b/admin/CPP-DEFINES
@@ -251,7 +251,6 @@ HAVE_RSVG
HAVE_SELECT
HAVE_SENDTO
HAVE_SEQPACKET
-HAVE_SETITIMER
HAVE_SETLOCALE
HAVE_SETRLIMIT
HAVE_SHARED_GAME_DIR
diff --git a/configure.ac b/configure.ac
index 6f3d7338c3..9277f3789f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4013,7 +4013,7 @@ AC_DEFUN
lrand48 random rint trunc \
select getpagesize setlocale newlocale \
getrlimit setrlimit shutdown \
-pthread_sigmask strsignal setitimer \
+pthread_sigmask strsignal \
sendto recvfrom getsockname getifaddrs freeifaddrs \
gai_strerror sync \
getpwent endpwent getgrent endgrent \
diff --git a/src/atimer.c b/src/atimer.c
index 505f6bcea1..5848627d45 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -113,7 +113,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp,
sigset_t oldset;
/* Round TIMESTAMP up to the next full second if we don't have itimers. */
-#if ! (defined HAVE_ITIMERSPEC || defined HAVE_SETITIMER)
+#ifndef HAVE_ITIMERSPEC
if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
timestamp = make_timespec (timestamp.tv_sec + 1, 0);
#endif
@@ -295,9 +295,6 @@ set_alarm (void)
{
if (atimers)
{
-#ifdef HAVE_SETITIMER
- struct itimerval it;
-#endif
struct timespec now, interval;
#ifdef HAVE_ITIMERSPEC
@@ -325,15 +322,7 @@ set_alarm (void)
interval = (timespec_cmp (atimers->expiration, now) <= 0
? make_timespec (0, 1000 * 1000)
: timespec_sub (atimers->expiration, now));
-
-#ifdef HAVE_SETITIMER
-
- memset (&it, 0, sizeof it);
- it.it_value = make_timeval (interval);
- setitimer (ITIMER_REAL, &it, 0);
-#else /* not HAVE_SETITIMER */
alarm (max (interval.tv_sec, 1));
-#endif /* not HAVE_SETITIMER */
}
}
@@ -495,7 +484,7 @@ debug_timer_callback (struct atimer *t)
else if (result >= 0)
{
bool intime = true;
-#if defined HAVE_ITIMERSPEC || defined HAVE_SETITIMER
+#ifdef HAVE_ITIMERSPEC
struct timespec delta = timespec_sub (now, r->expected);
/* Too late if later than expected + 0.02s. FIXME:
this should depend from system clock resolution. */
diff --git a/src/profiler.c b/src/profiler.c
index 7330f8861f..23b82600f3 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -202,9 +202,8 @@ static bool profiler_timer_ok;
static enum profiler_cpu_running
{ NOT_RUNNING,
#ifdef HAVE_ITIMERSPEC
- TIMER_SETTIME_RUNNING,
+ TIMER_SETTIME_RUNNING
#endif
- SETITIMER_RUNNING
}
profiler_cpu_running;
@@ -262,7 +261,6 @@ static int
setup_cpu_timer (Lisp_Object sampling_interval)
{
struct sigaction action;
- struct itimerval timer;
struct timespec interval;
int billion = 1000000000;
@@ -318,12 +316,6 @@ setup_cpu_timer (Lisp_Object sampling_interval)
}
#endif
-#ifdef HAVE_SETITIMER
- timer.it_value = timer.it_interval = make_timeval (interval);
- if (setitimer (ITIMER_PROF, &timer, 0) == 0)
- return SETITIMER_RUNNING;
-#endif
-
return NOT_RUNNING;
}
@@ -380,16 +372,6 @@ Return non-nil if the profiler was running. */)
}
break;
#endif
-
-#ifdef HAVE_SETITIMER
- case SETITIMER_RUNNING:
- {
- struct itimerval disable;
- memset (&disable, 0, sizeof disable);
- setitimer (ITIMER_PROF, &disable, 0);
- }
- break;
-#endif
}
signal (SIGPROF, SIG_IGN);
diff --git a/src/syssignal.h b/src/syssignal.h
index 0887eacb05..790413178e 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -47,8 +47,7 @@ extern void unblock_tty_out_signal (sigset_t const *);
# define HAVE_ITIMERSPEC
#endif
-#if (defined SIGPROF && !defined PROFILING \
- && (defined HAVE_SETITIMER || defined HAVE_ITIMERSPEC))
+#if defined SIGPROF && !defined PROFILING && defined HAVE_ITIMERSPEC
# define PROFILER_CPU_SUPPORT
#endif
--
2.17.1
[-- Attachment #3: 0002-Adjust-w32-to-emulate-timer_settime-not-setitimer.patch --]
[-- Type: text/x-patch, Size: 12777 bytes --]
From aeec1bcc629a722cba7413287f965e4ab3dc9495 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sun, 16 Sep 2018 12:35:58 -0700
Subject: [PATCH 2/2] Adjust w32 to emulate timer_settime, not setitimer
This adjusts the w32 code to emulate the current timer_settime etc.
functions instead of the obsolescent setitimer etc. functions.
* nt/inc/sys/time.h (ITIMER_REAL, ITIMER_PROF):
Remove. All uses removed.
(struct itimerspec, pthread_attr_t, union sigval, struct sigevent)
(SIGEV_SIGNAL, TIMER_ABSTIME, CLOCK_REALTIME)
(CLOCK_THREAD_CPUTIME_ID, timer_t): New definitions.
* src/w32proc.c (struct itimer_data, stop_timer_thread):
(start_timer_thread):
Clock type is now clockid_t, not int.
All uses changed.
(timer_create, timer_gettime, timer_settime):
New functions, replacing getitimer and setitimer.
All uses changed.
---
nt/inc/sys/time.h | 38 +++++++++---
src/w32proc.c | 143 ++++++++++++++++++++++++----------------------
2 files changed, 106 insertions(+), 75 deletions(-)
diff --git a/nt/inc/sys/time.h b/nt/inc/sys/time.h
index 6f67e5db4e..d03bc456ea 100644
--- a/nt/inc/sys/time.h
+++ b/nt/inc/sys/time.h
@@ -3,19 +3,41 @@
#include_next <sys/time.h>
-#define ITIMER_REAL 0
-#define ITIMER_PROF 1
+struct itimerspec
+{
+ struct timespec it_interval; /* timer interval */
+ struct timespec it_value; /* current value */
+};
-struct itimerval
+typedef struct pthread_attr_t *pthread_attr_t;
+union sigval
+{
+ int sival_int;
+ void *sival_ptr;
+};
+struct sigevent
{
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
+ int sigev_notify;
+ int sigev_signo;
+ union sigval sigev_value;
+ void (*sigev_notify_function) (union sigval);
+ pthread_attr_t *sigev_notify_attributes;
};
+#define SIGEV_SIGNAL 0
-int getitimer (int, struct itimerval *);
-int setitimer (int, struct itimerval *, struct itimerval *);
+#define TIMER_ABSTIME 1
+typedef enum { CLOCK_REALTIME, CLOCK_THREAD_CPUTIME_ID } clockid_t;
+#define CLOCK_REALTIME CLOCK_REALTIME
+#define CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID
+typedef struct
+{
+ clockid_t clockid;
+} timer_t;
+int timer_create (clockid_t, struct sigevent *restrict, timer_t *restrict);
+int timer_settime (timer_t, int, struct itimerspec const *,
+ struct itimerspec *restrict);
+int timer_getoverrun (timer_t);
#endif /* SYS_TIME_H_INCLUDED */
/* end of sys/time.h */
-
diff --git a/src/w32proc.c b/src/w32proc.c
index cb02ba6341..23869768cf 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -89,7 +89,7 @@ sys_signal (int sig, signal_handler handler)
signal_handler old;
/* SIGCHLD is needed for supporting subprocesses, see sys_kill
- below. SIGALRM and SIGPROF are used by setitimer. All the
+ below. SIGALRM and SIGPROF are used by timer_settime. All the
others are the only ones supported by the MS runtime. */
if (!(sig == SIGINT || sig == SIGSEGV || sig == SIGILL
|| sig == SIGFPE || sig == SIGABRT || sig == SIGTERM
@@ -261,7 +261,8 @@ setsid (void)
/* Emulations of interval timers.
- Limitations: only ITIMER_REAL and ITIMER_PROF are supported.
+ Limitations: only CLOCK_REALTIME and CLOCK_THREAD_CPUTIME_ID are
+ supported, and only a single timer of each time is supported.
Implementation: a separate thread is started for each timer type,
the thread calls the appropriate signal handler when the timer
@@ -271,7 +272,7 @@ struct itimer_data {
volatile ULONGLONG expire;
volatile ULONGLONG reload;
volatile int terminate;
- int type;
+ clockid_t type;
HANDLE caller_thread;
HANDLE timer_thread;
};
@@ -357,11 +358,11 @@ static DWORD WINAPI
timer_loop (LPVOID arg)
{
struct itimer_data *itimer = (struct itimer_data *)arg;
- int which = itimer->type;
- int sig = (which == ITIMER_REAL) ? SIGALRM : SIGPROF;
- CRITICAL_SECTION *crit = (which == ITIMER_REAL) ? &crit_real : &crit_prof;
+ bool realtime = itimer->type == CLOCK_REALTIME;
+ int sig = realtime ? SIGALRM : SIGPROF;
+ CRITICAL_SECTION *crit = realtime ? &crit_real : &crit_prof;
const DWORD max_sleep = MAX_SINGLE_SLEEP * 1000 / TIMER_TICKS_PER_SEC;
- HANDLE hth = (which == ITIMER_REAL) ? NULL : itimer->caller_thread;
+ HANDLE hth = realtime ? NULL : itimer->caller_thread;
while (1)
{
@@ -369,7 +370,7 @@ timer_loop (LPVOID arg)
signal_handler handler;
ULONGLONG now, expire, reload;
- /* Load new values if requested by setitimer. */
+ /* Load new values if requested by timer_settime. */
EnterCriticalSection (crit);
expire = itimer->expire;
reload = itimer->reload;
@@ -480,10 +481,10 @@ timer_loop (LPVOID arg)
}
static void
-stop_timer_thread (int which)
+stop_timer_thread (clockid_t clockid)
{
struct itimer_data *itimer =
- (which == ITIMER_REAL) ? &real_itimer : &prof_itimer;
+ clockid == CLOCK_REALTIME ? &real_itimer : &prof_itimer;
int i;
DWORD err = 0, exit_code = 255;
BOOL status;
@@ -526,9 +527,9 @@ void
term_timers (void)
{
if (real_itimer.timer_thread)
- stop_timer_thread (ITIMER_REAL);
+ stop_timer_thread (CLOCK_REALTIME);
if (prof_itimer.timer_thread)
- stop_timer_thread (ITIMER_PROF);
+ stop_timer_thread (CLOCK_THREAD_CPUTIME_ID);
/* We are going to delete the critical sections, so timers cannot
work after this. */
@@ -564,12 +565,12 @@ init_timers (void)
}
static int
-start_timer_thread (int which)
+start_timer_thread (clockid_t clockid)
{
DWORD exit_code, tid;
HANDLE th;
struct itimer_data *itimer =
- (which == ITIMER_REAL) ? &real_itimer : &prof_itimer;
+ clockid == CLOCK_REALTIME ? &real_itimer : &prof_itimer;
if (itimer->timer_thread
&& GetExitCodeThread (itimer->timer_thread, &exit_code)
@@ -597,7 +598,7 @@ start_timer_thread (int which)
return -1;
}
itimer->terminate = 0;
- itimer->type = which;
+ itimer->type = clockid;
itimer->caller_thread = th;
/* Request that no more than 64KB of stack be reserved for this
thread, to avoid reserving too much memory, which would get in
@@ -616,24 +617,42 @@ start_timer_thread (int which)
/* This is needed to make sure that the timer thread running for
profiling gets CPU as soon as the Sleep call terminates. */
- if (which == ITIMER_PROF)
+ if (clockid == CLOCK_THREAD_CPUTIME_ID)
SetThreadPriority (itimer->timer_thread, THREAD_PRIORITY_TIME_CRITICAL);
return 0;
}
-/* Most of the code of getitimer and setitimer (but not of their
+int
+timer_create (clockid_t clockid, struct sigevent *restrict evp,
+ timer_t *restrict timerid)
+{
+ if ((clockid == CLOCK_REALTIME || clockid == CLOCK_THREAD_CPUTIME_ID)
+ && (!evp || (evp->sigev_notify == SIGEV_SIGNAL
+ && evp->sigev_signo == (clockid == CLOCK_REALTIME
+ ? SIGALRM : SIGPROF)
+ && evp->sigev_value.sival_ptr == timerid)))
+ {
+ timerid->clockid = clockid;
+ return 0;
+ }
+ errno = EINVAL;
+ return -1;
+}
+
+/* Most of the code of timer_gettime and timer_settime (but not of their
subroutines) was shamelessly stolen from itimer.c in the DJGPP
library, see www.delorie.com/djgpp. */
int
-getitimer (int which, struct itimerval *value)
+timer_gettime (timer_t timerid, struct itimerspec *value)
{
volatile ULONGLONG *t_expire;
volatile ULONGLONG *t_reload;
ULONGLONG expire, reload;
- __int64 usecs;
CRITICAL_SECTION *crit;
struct itimer_data *itimer;
+ HANDLE thread_hand;
+ bool realtime = timerid.clockid == CLOCK_REALTIME;
if (disable_itimers)
return -1;
@@ -644,21 +663,18 @@ getitimer (int which, struct itimerval *value)
return -1;
}
- if (which != ITIMER_REAL && which != ITIMER_PROF)
- {
- errno = EINVAL;
- return -1;
- }
-
- itimer = (which == ITIMER_REAL) ? &real_itimer : &prof_itimer;
+ itimer = realtime ? &real_itimer : &prof_itimer;
- ticks_now = w32_get_timer_time ((which == ITIMER_REAL)
+ ticks_now = w32_get_timer_time (realtime
? NULL
: GetCurrentThread ());
+ itimer = realtime ? &real_itimer : &prof_itimer;
+
+ ticks_now = w32_get_timer_time (thread_hand);
t_expire = &itimer->expire;
t_reload = &itimer->reload;
- crit = (which == ITIMER_REAL) ? &crit_real : &crit_prof;
+ crit = realtime ? &crit_real : &crit_prof;
EnterCriticalSection (crit);
reload = *t_reload;
@@ -669,25 +685,25 @@ getitimer (int which, struct itimerval *value)
expire -= ticks_now;
value->it_value.tv_sec = expire / TIMER_TICKS_PER_SEC;
- usecs =
- (expire % TIMER_TICKS_PER_SEC) * (__int64)1000000 / TIMER_TICKS_PER_SEC;
- value->it_value.tv_usec = usecs;
+ value->it_value.tv_nsec = (expire % TIMER_TICKS_PER_SEC
+ * (1000000000 / TIMER_TICKS_PER_SEC));
value->it_interval.tv_sec = reload / TIMER_TICKS_PER_SEC;
- usecs =
- (reload % TIMER_TICKS_PER_SEC) * (__int64)1000000 / TIMER_TICKS_PER_SEC;
- value->it_interval.tv_usec= usecs;
-
+ value->it_interval.tv_nsec= (reload % TIMER_TICKS_PER_SEC
+ * (1000000000 / TIMER_TICKS_PER_SEC));
return 0;
}
int
-setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
+timer_settime (timer_t timerid, int flags,
+ struct itimerspec const *restrict value,
+ struct itimerspec *restrict ovalue)
{
volatile ULONGLONG *t_expire, *t_reload;
ULONGLONG expire, reload, expire_old, reload_old;
- __int64 usecs;
+ int ns;
CRITICAL_SECTION *crit;
- struct itimerval tem, *ptem;
+ struct itimerspec tem, *ptem;
+ bool realtime = timerid.clockid == CLOCK_REALTIME;
if (disable_itimers)
return -1;
@@ -710,18 +726,15 @@ setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
else
ptem = &tem;
- if (getitimer (which, ptem)) /* also sets ticks_now */
+ if (timer_gettime (timerid, ptem)) /* also sets ticks_now */
return -1; /* errno already set */
- t_expire =
- (which == ITIMER_REAL) ? &real_itimer.expire : &prof_itimer.expire;
- t_reload =
- (which == ITIMER_REAL) ? &real_itimer.reload : &prof_itimer.reload;
-
- crit = (which == ITIMER_REAL) ? &crit_real : &crit_prof;
+ t_expire = realtime ? &real_itimer.expire : &prof_itimer.expire;
+ t_reload = realtime ? &real_itimer.reload : &prof_itimer.reload;
+ crit = realtime ? &crit_real : &crit_prof;
if (!value
- || (value->it_value.tv_sec == 0 && value->it_value.tv_usec == 0))
+ || (value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0))
{
EnterCriticalSection (crit);
/* Disable the timer. */
@@ -733,28 +746,23 @@ setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
reload = value->it_interval.tv_sec * TIMER_TICKS_PER_SEC;
- usecs = value->it_interval.tv_usec;
+ ns = value->it_interval.tv_nsec;
if (value->it_interval.tv_sec == 0
- && usecs && usecs * TIMER_TICKS_PER_SEC < clocks_min * 1000000)
+ && 0 < ns && ns < clocks_min * (1000000000 / TIMER_TICKS_PER_SEC))
reload = clocks_min;
else
- {
- usecs *= TIMER_TICKS_PER_SEC;
- reload += usecs / 1000000;
- }
+ reload += ns / (1000000000 / TIMER_TICKS_PER_SEC);
- expire = value->it_value.tv_sec * TIMER_TICKS_PER_SEC;
- usecs = value->it_value.tv_usec;
- if (value->it_value.tv_sec == 0
- && usecs * TIMER_TICKS_PER_SEC < clocks_min * 1000000)
+ expire = ex.tv_sec * TIMER_TICKS_PER_SEC;
+ ns = ex.tv_nsec;
+ if (ex.tv_sec == 0
+ && 0 < ns && ns < clocks_min * (1000000000 / TIMER_TICKS_PER_SEC))
expire = clocks_min;
else
- {
- usecs *= TIMER_TICKS_PER_SEC;
- expire += usecs / 1000000;
- }
+ reload += ns / (1000000000 / TIMER_TICKS_PER_SEC);
- expire += ticks_now;
+ if (flags & TIMER_ABSTIME)
+ expire += ticks_now;
EnterCriticalSection (crit);
expire_old = *t_expire;
@@ -766,20 +774,21 @@ setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
}
LeaveCriticalSection (crit);
- return start_timer_thread (which);
+ return start_timer_thread (timerid.clockid);
}
int
alarm (int seconds)
{
-#ifdef HAVE_SETITIMER
- struct itimerval new_values, old_values;
+#ifdef HAVE_ITIMERSPEC
+ struct itimerspec new_values, old_values;
new_values.it_value.tv_sec = seconds;
- new_values.it_value.tv_usec = 0;
- new_values.it_interval.tv_sec = new_values.it_interval.tv_usec = 0;
+ new_values.it_value.tv_nsec = 0;
+ new_values.it_interval.tv_sec = new_values.it_interval.tv_nsec = 0;
- if (setitimer (ITIMER_REAL, &new_values, &old_values) < 0)
+ timer_t id = { .clockid = CLOCK_REALTIME };
+ if (timer_settime (id, 0, &new_values, &old_values) < 0)
return 0;
return old_values.it_value.tv_sec;
#else
--
2.17.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* bug#32746: stop using obsolescent setitimer API
2018-09-16 20:19 bug#32746: stop using obsolescent setitimer API Paul Eggert
@ 2018-09-17 15:01 ` Eli Zaretskii
0 siblings, 0 replies; 2+ messages in thread
From: Eli Zaretskii @ 2018-09-17 15:01 UTC (permalink / raw)
To: Paul Eggert; +Cc: 32746
> From: Paul Eggert <eggert@cs.ucla.edu>
> Date: Sun, 16 Sep 2018 13:19:45 -0700
>
> POSIX obsoleted the getitimer/setitimer API a decade ago, and now's a good time
> for Emacs to stop using this obsolescent API, partly to simplify other timestamp
> improvements that I have in mind, partly to head off any other lurking bugs like
> the problem I just fixed in commit 238c7cd730819ddba2dbde3c46ee36136575695b
> relating to a mistaken assumption about the old API.
>
> Attached please find two proposed patches. The first simplifies Emacs proper to
> just use the current timer_gettime/timer_settime API instead (this is the
> standard replacement for the obsolescent API). The second patch affects only the
> MS-Windows code, modifying it to use the new API instead of the old one; I
> haven't tested it as I don't use MS-Windows.
Thanks, I have a couple of comments/questions about the MS-Windows
changes (thanks for working on that):
> +struct sigevent
> {
> - struct timeval it_interval; /* timer interval */
> - struct timeval it_value; /* current value */
> + int sigev_notify;
> + int sigev_signo;
> + union sigval sigev_value;
> + void (*sigev_notify_function) (union sigval);
> + pthread_attr_t *sigev_notify_attributes;
I'd prefer not to use pthread_attr_t, as that could clash with some
MinGW header.
> +typedef enum { CLOCK_REALTIME, CLOCK_THREAD_CPUTIME_ID } clockid_t;
Some versions of MinGW have clockid_t (for clock_gettime and
clock_settime), so this might cause conflicts.
> +#define CLOCK_REALTIME CLOCK_REALTIME
> +#define CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID
Some of these are declared/defined in MinGW headers in some versions.
> + HANDLE thread_hand;
This seems to be unused, and is probably related to the other issues
below.
> - itimer = (which == ITIMER_REAL) ? &real_itimer : &prof_itimer;
> + itimer = realtime ? &real_itimer : &prof_itimer;
>
> - ticks_now = w32_get_timer_time ((which == ITIMER_REAL)
> + ticks_now = w32_get_timer_time (realtime
> ? NULL
> : GetCurrentThread ());
>
> + itimer = realtime ? &real_itimer : &prof_itimer;
> +
> + ticks_now = w32_get_timer_time (thread_hand);
This seems to do the same stuff twicer, using thread_hand that is
uninitialized.
> - expire = value->it_value.tv_sec * TIMER_TICKS_PER_SEC;
> - usecs = value->it_value.tv_usec;
> - if (value->it_value.tv_sec == 0
> - && usecs * TIMER_TICKS_PER_SEC < clocks_min * 1000000)
> + expire = ex.tv_sec * TIMER_TICKS_PER_SEC;
> + ns = ex.tv_nsec;
> + if (ex.tv_sec == 0
> + && 0 < ns && ns < clocks_min * (1000000000 / TIMER_TICKS_PER_SEC))
> expire = clocks_min;
This seems to use an undefined variable 'ex'.
> - expire += ticks_now;
> + if (flags & TIMER_ABSTIME)
> + expire += ticks_now;
I don't think I understand the reason for the condition you added.
> +#ifdef HAVE_ITIMERSPEC
If we will have a test for itimerspec, we will probably need to edit
nt/mingw-cfg.site to keep the configure script happy.
Thanks again for working on this.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-09-17 15:01 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-16 20:19 bug#32746: stop using obsolescent setitimer API Paul Eggert
2018-09-17 15:01 ` Eli Zaretskii
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).