From: Marco Antoniotti
Subject: Adding Missing System Calls to CMUCL
Date: 
Message-ID: <MARCOXA.94Apr28143603@graphics.cs.nyu.edu>
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