From 404e5c4091c607a39d28b651063da9bdc7ebb3bb Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 1 Aug 2014 22:13:11 -0700 Subject: * configure (have_sys_time): New variable. Added check for setitimer/getitimer which also checks for . * signal.c (sig_init): Register itimer-real, itimer-virtual, itimer-prof variables and getitimer and setitimer functions. (tv_to_usec): New static function. (getitimer_wrap, setitimer_wrap): New functions. * signal.h (getitimer_wrap, setitimer_wrap): Declared. * txr.1: Documented itimers. --- ChangeLog | 15 +++++++++++++++ configure | 28 ++++++++++++++++++++++++++++ signal.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ signal.h | 5 +++++ txr.1 | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+) diff --git a/ChangeLog b/ChangeLog index dbcb0a68..f577bad7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2014-08-01 Kaz Kylheku + + * configure (have_sys_time): New variable. + Added check for setitimer/getitimer which also + checks for . + + * signal.c (sig_init): Register itimer-real, itimer-virtual, + itimer-prof variables and getitimer and setitimer functions. + (tv_to_usec): New static function. + (getitimer_wrap, setitimer_wrap): New functions. + + * signal.h (getitimer_wrap, setitimer_wrap): Declared. + + * txr.1: Documented itimers. + 2014-08-01 Kaz Kylheku * signal.c (set_sig_handler): Don't use SA_ONSTACK diff --git a/configure b/configure index 6151327b..33c87103 100755 --- a/configure +++ b/configure @@ -114,6 +114,7 @@ mpi_version=1.8.6 have_quilt= have_patch= have_unistd= +have_sys_time= have_timegm= have_syslog= have_windows_h= @@ -1709,6 +1710,29 @@ else printf "no\n" fi +printf "Checking for setitimer/getitimer ... " + +cat > conftest.c < + +int main(void) +{ + struct itimerval itv, itv2; + int err; + err = getitimer(ITIMER_REAL, &itv); + err = getitimer(ITIMER_VIRTUAL, &itv); + err = setitimer(ITIMER_VIRTUAL, &itv, &itv2); + return 0; +} +! +if conftest ; then + printf "yes\n" + printf "#define HAVE_ITIMER 1\n" >> config.h + have_sys_time=y +else + printf "no\n" +fi + printf "Checking for makedev ... " cat > conftest.c <> config.h fi +if [ -n "$have_sys_time" ] ; then + printf "#define HAVE_SYS_TIME 1\n" >> config.h +fi + if [ -n "$have_windows_h" ] ; then printf "#define HAVE_WINDOWS_H 1\n" >> config.h fi diff --git a/signal.c b/signal.c index 305fee89..35e55fa3 100644 --- a/signal.c +++ b/signal.c @@ -34,6 +34,9 @@ #include #include #include "config.h" +#if HAVE_SYS_TIME +#include +#endif #include "lib.h" #include "gc.h" #include "signal.h" @@ -156,6 +159,14 @@ void sig_init(void) reg_var(intern(lit("sig-pwr"), user_package), num_fast(SIGPWR)); #endif +#if HAVE_ITIMER + reg_var(intern(lit("itimer-real"), user_package), num_fast(ITIMER_REAL)); + reg_var(intern(lit("itimer-virtual"), user_package), num_fast(ITIMER_VIRTUAL)); + reg_var(intern(lit("itimer-prov"), user_package), num_fast(ITIMER_PROF)); + reg_fun(intern(lit("getitimer"), user_package), func_n1(getitimer_wrap)); + reg_fun(intern(lit("setitimer"), user_package), func_n3(setitimer_wrap)); +#endif + reg_fun(intern(lit("set-sig-handler"), user_package), func_n2(set_sig_handler)); reg_fun(intern(lit("get-sig-handler"), user_package), func_n1(get_sig_handler)); reg_fun(intern(lit("sig-check"), user_package), func_n0(sig_check)); @@ -332,3 +343,43 @@ int sig_mask(int how, const sigset_t *set, sigset_t *oldset) *oldset = sig_blocked_cache; return 0; } + +#if HAVE_ITIMER + +static val tv_to_usec(val sec, val usec) +{ + const val meg = num_fast(1000000); + return plus(mul(sec, meg), usec); +} + +val getitimer_wrap(val which) +{ + struct itimerval itv; + + if (getitimer(c_num(which), &itv) < 0) + return nil; + + return list(tv_to_usec(num(itv.it_interval.tv_sec), num(itv.it_interval.tv_usec)), + tv_to_usec(num(itv.it_value.tv_sec), num(itv.it_value.tv_usec)), + nao); +} + +val setitimer_wrap(val which, val interval, val currval) +{ + struct itimerval itn, itv; + const val meg = num_fast(1000000); + + itn.it_interval.tv_sec = c_num(trunc(interval, meg)); + itn.it_interval.tv_usec = c_num(mod(interval, meg)); + itn.it_value.tv_sec = c_num(trunc(currval, meg)); + itn.it_value.tv_usec = c_num(mod(currval, meg)); + + if (setitimer(c_num(which), &itn, &itv) < 0) + return nil; + + return list(tv_to_usec(num(itv.it_interval.tv_sec), num(itv.it_interval.tv_usec)), + tv_to_usec(num(itv.it_value.tv_sec), num(itv.it_value.tv_usec)), + nao); +} + +#endif diff --git a/signal.h b/signal.h index 63a9bb8d..4fe9d823 100644 --- a/signal.h +++ b/signal.h @@ -124,3 +124,8 @@ val sig_check(void); #if HAVE_POSIX_SIGS int sig_mask(int how, const sigset_t *set, sigset_t *oldset); #endif + +#if HAVE_ITIMER +val getitimer_wrap(val which); +val setitimer_wrap(val which, val interval, val currval); +#endif diff --git a/txr.1 b/txr.1 index 176d665c..2f9efc99 100644 --- a/txr.1 +++ b/txr.1 @@ -14608,6 +14608,43 @@ It is a wrapper for the POSIX kill function. If the argument is omitted, it defaults to the same value as sig-term. +.SH UNIX ITIMERS + +Itimers can be used in combination with signal handling to execute asynchronous +actions. Itimers deliver one-time or periodic signals. For more information, +consult the POSIX specification. + +.SS Variables itimer-real, itimer-virtual and itimer-prof + +.TP +Description: + +These variables correspond to the POSIX constants ITIMER_REAL, ITIMER_VIRTUAL +and ITIMER_PROF. Thir values are suitable as the argument of +the getitimer and setitimer functions. + +.SS Functions getitimer and setitimer + +.TP +Syntax: + + (getitimer ) + (setitimer ) + +.TP +Description + +The getitimer function returns the current value of the specified timer, +which must be itimer-real, itimer-virtual or itimer-prof. + +The current value consists of a list of two integer values, which +represents microseconds. The first value is the timer interval, +and the second value is the timer's current value. + +The setitimer function also retrieves the specified timer, exactly +as getitimer. In addition, it stores a new value in the timer, +which is given by the two arguments, expressed in microseconds. + .SH UNIX SYSLOG On platforms where a Unix-like syslog API is available, TXR exports this -- cgit v1.2.3