Good Afternoon,
Any help would be appreciated!
CMUCL is a fine piece of software, but here and there it lacks
documentation ... and pieces.
I am trying to use the SunOS system calls 'setitimer' and 'getitimer'.
After some digging in the CMUCL source code I found that the relevant
structures are defined, but the system calls are not.
In file .../code/unix.lisp you can find
-------------------------------------------------------------------------------
;;; From sys/time.h
(def-alien-type nil
(struct timeval
(tv-sec long) ; seconds
(tv-usec long))) ; and microseconds
(def-alien-type nil
(struct timezone
(tz-minuteswest int) ; minutes west of Greenwich
(tz-dsttime ; type of dst correction
(enum nil :none :usa :aust :wet :met :eet :can))))
(def-alien-type nil
(struct itimerval
(it-interval (struct timeval)) ; timer interval
(it-value (struct timeval)))) ; current value
-------------------------------------------------------------------------------
But no trace of the two system calls (which instead are present in the
'syscall.lisp' file, which I decided does not get loaded since it
refers to the "MACH" package).
Therefore I set out to write the two functions and came up with the
following result.
-------------------------------------------------------------------------------
;;; -*- Mode: CLtL -*-
;;; unix-timers.lisp --
;;; CMUCL 17e does not provide many system calls which are found in
;;; SunOS.
;;; 'setitimer' and 'getitimer' are sorely missing. I'd also like to
;;; add 'ualarm' which is a simpler interface to the timer syscalls.
;;;
;;; Copyright (C) 1994 Marco Antoniotti
;;;
;;; Author: Marco Antoniotti
;;;
;;; Address: Robotics Laboratory
;;; Courant Institute for Mathematical Sciences
;;; New York University
;;; 719 Broadway, 1220
;;; New York, NY, 10003, U.S.A.
;;;
;;; $Id: SunOS-timers.lisp,v 1.1 1994/04/27 21:47:55 marcoxa Exp marcoxa $
;;;
;;; History:
;;; $Log: SunOS-timers.lisp,v $
;;; Revision 1.1 1994/04/27 21:47:55 marcoxa
;;; Initial revision
;;;
;;;============================================================================
;;; Prologue
(in-package "UNIX")
(use-package "ALIEN")
(use-package "C-CALL")
(use-package "SYSTEM")
(use-package "EXT")
(export '(setitimer
getitimer
ualarm))
;;;============================================================================
;;; Global Declarations
;;; ITIMER-REAL, ITIMER-VIRTUAL, ITIMER-PROF --
;;; Lifted from 'syscall.lisp' in the CMUCL source code, where the
;;; MACH syscalls are held.
;;; Check also <sys/time.h> for the SunOS C declaration.
(defconstant ITIMER-REAL 0 "SunOS Real time intervals.")
(defconstant ITIMER-VIRTUAL 1 "SunOS Virtual time intervals.")
(defconstant ITIMER-PROF 2 "SunOS User/system virtual time.")
;;;============================================================================
;;; Functions
;;; setitimer which itimer-spec &optional result-itimerval --
;;; I do not follow the same conventions found for the MACH 'setitimer'.
;;; Instead, I stick to the standard SunOS definition.
#+:SUNOS
(defun setitimer (which itimer-spec
&optional
(result-itimerval
(make-alien (struct itimerval))))
"UNIX (SunOS) system call."
;; Not necessary to initialize 'result-itimerval'.
(declare (fixnum which))
(syscall ("setitimer" int
(* (struct itimerval))
(* (struct itimerval)))
result-itimerval
(coerce which '(signed-byte 32))
itimer-spec
result-itimerval))
;;; getitimer which &optional result-itimerval --
#+:SUNOS
(defun getitimer (which &optional
(result-itimerval
(make-alien (struct itimerval))))
"UNIX (SunOS) system call."
;; Not necessary to initialize 'result-itimerval'.
(declare (fixnum which))
(syscall ("getitimer" int (* (struct itimerval)))
result-itimerval
(coerce which '(signed-byte 32))
result-itimerval))
;;;============================================================================
;;; Test
(defvar *test-itimer*
(make-alien (struct itimerval)))
(defun test-itimer ()
(let ((i 10))
(declare (fixnum i))
(flet ((alarm-handler ()
(if (plusp (decf i))
(print "ZUT!")
(enable-interrupt :sigalrm #'sigalrm-handler)))
)
(setf (slot (slot *test-itimer* 'it-interval) 'tv-sec) 2)
(setf (slot (slot *test-itimer* 'it-interval) 'tv-sec) 0)
(setf (slot (slot *test-itimer* 'it-value) 'tv-sec) 2)
(setf (slot (slot *test-itimer* 'it-value) 'tv-sec) 0)
(enable-interrupt :sigalrm #'alarm-handler)
(setitimer itimer-real *test-itimer*))))
;;; -- end of file -- unix-timers.lisp
-------------------------------------------------------------------------------
Running the test (with 'alien:alien-funcall' traced) yields
-------------------------------------------------------------------------------
* (unix::test-itimer)
0: (ALIEN-FUNCALL
#<Alien (FUNCTION SYSTEM-AREA-POINTER (UNSIGNED 32)) at #x00019A68>
16)
0: ALIEN-FUNCALL returned #.(INT-SAP #x00046E28)
0: (ALIEN-FUNCALL
#<Alien (FUNCTION (SIGNED 32) (SIGNED 32) (* #) (* #)) at #x00024600>
0
#<Alien (* (STRUCT ITIMERVAL # #)) at #x000469D8>
#<Alien (* (STRUCT ITIMERVAL # #)) at #x00046E28>)
0: ALIEN-FUNCALL returned -1
NIL
22
-------------------------------------------------------------------------------
Which (I suppose) means that the system call failed (errno 22 =
EINVAL: Invalid Argument).
I am obviously missing something.
Therefore I need help.
Why am I sending this over the net instead of ··········@cs.cmu.edu.
For two reasons:
1 - the folks at CMU read this newsgroup
2 - since they are now running CMULISP as a side show, any work that
can be done through the net will have much more impact and will
help everybody who uses CMULISP.
Thanks for your time
--
Marco Antoniotti - Resistente Umano
-------------------------------------------------------------------------------
Robotics Lab | room: 1220 - tel. #: (212) 998 3370
Courant Institute NYU | e-mail: ·······@cs.nyu.edu
...e` la semplicita` che e` difficile a farsi.
...it is simplicity that is difficult to make.
Bertholdt Brecht