;;; -*- Mode:LISP; Package:TCP; Base:10; Patch-File:T; Readtable:ZL -*- (DEFVAR *HANDLE-OWN-EXINTR-WINS* 0) (DEFVAR *HANDLE-OWN-EXINTR-CALLS* 0) (DEFVAR *HANDLE-OWN-EXINTR-BUSY* 200) (DEFUN HANDLE-OWN-EXINTR-STATS (&OPTIONAL RESETP) (FORMAT T "~&~D calls, ~D wins, ~D percent, BUSY LOOP COUNT = ~D~%" *HANDLE-OWN-EXINTR-CALLS* *HANDLE-OWN-EXINTR-WINS* (ROUND (TIMES *HANDLE-OWN-EXINTR-WINS* 100) (IF (ZEROP *HANDLE-OWN-EXINTR-CALLS*) 1 *HANDLE-OWN-EXINTR-CALLS*)) *HANDLE-OWN-EXINTR-BUSY* ) (when RESETP (setq *HANDLE-OWN-EXINTR-WINS* 0) (setq *HANDLE-OWN-EXINTR-CALLS* 0))) (DEFUN EXINTR-MESSAGE-READYP () (ZEROP (LOGAND (READ-UCHAR *DMA* (MSG-OFFSET (RMSG-AREA-LASTR RMSGAREA)) 'MESSAGES-STATUS) (LOGIOR MQ-DONE MQ-EXOS)))) (DEFUN EXINTR-WAIT () (PROCESS-WAIT "Exintr wait" #'(LAMBDA () (WHEN (AND (NOT (EQ *EXINTR-IN-PROCESS* :USER)) (EXINTR-MESSAGE-READYP)) ;; Note, just because the wait function returns T doesnt ;; mean that our process will be run next. That is why ;; we use the flag values of NIL, :SYSTEM, :USER rather than ;; just T and NIL. (SETQ *EXINTR-IN-PROCESS* :SYSTEM))))) (DEFUN HANDLE-OWN-EXINTR (KP) (WHEN (%STORE-CONDITIONAL (LOCF *EXINTR-IN-PROCESS*) NIL :USER) (INCF *HANDLE-OWN-EXINTR-CALLS*) (DO ((J 0 (1+ J))) ((OR (EXINTR-MESSAGE-READYP) (= J *HANDLE-OWN-EXINTR-BUSY*)))) (PROG1 (DO ((K 1 (1+ K))) ((NOT (EXINTR-MESSAGE-READYP)) NIL) (EXINTR) (COND ((KP-READYP KP) (RETURN (INCF *HANDLE-OWN-EXINTR-WINS*))) ((= K 3) (RETURN NIL)))) (SETQ *EXINTR-IN-PROCESS* NIL)))) (DEFUN BUSY-TIME () (LET ((OFFSET (+ (MSG-OFFSET (RMSG-AREA-LASTR RMSGAREA)) MESSAGES-STATUS)) (MASK (LOGIOR MQ-DONE MQ-EXOS))) (LET ((X (TIME:MICROSECOND-TIME))) (DO ((J 0 (1+ J))) ((OR (ZEROP (LOGAND MASK (AREF *DMA* OFFSET))) (= J *HANDLE-OWN-EXINTR-BUSY*)))) (- (TIME:MICROSECOND-TIME) X)))) ;;; we know that about 25 process switches per second of the kind we need. ;; that is 66 milliseconds. A count of 100 is only 5 miliseconds. (DEFUN BUSY-TIME-TEST () (FORMAT T "~&COUNT milliseconds used~%") (DOTIMES (J 10) (LET ((*HANDLE-OWN-EXINTR-BUSY* (* J 30))) (FORMAT T "~4D ~$~%" *HANDLE-OWN-EXINTR-BUSY* (QUOTIENT (BUSY-TIME) 1000.0)))))