Lisp HUG Maillist Archive

aberrations in a scheduler loop

Hi,

I generally work with the professional edition of LWM on an Intel Mac.
Sometimes I test my code on a powerPC G5 (single processor 2 Ghz)
using the personal edition of LW. In this situation I encountered a
very strange problem and I can't understand if this problem is related
to the different hardware used or (maybe) to the heap size limitation
of the personal edition.

Simplified, my code (a scheduler loop) get the host clock time, do
something, sleep for ± one MSec, and retain the clock in a variable
for the next iteration.
After a lot of efforts to understand the strange things I observed, I
added this test in the loop :

IF the current clock is smaller than the previous clock
THEN print a list of the form (current previous)

And I was surprised to got these printouts (for a test of maybe two or
three minutes) :

(253954744459 256124475163)
(253954744459 256199840389)
(253954744459 256414704970)
(253954744459 257016437709)
(253954744459 257158069959)
(253954744459 257228130901)
(253954744459 257483039210)
(258249711755 258686301949)
(258249711755 258828856542)
(258249711755 258830737132)
(258249711755 258838794217)
(258249711755 259432733868)
(258249711755 259456775185)
(258249711755 260004755879)

where 'current' is actually smaller than 'previous' (witch is already
very strange...), and where 'current' is also always the same number
for some periods...

some clues :

- during one of these test, I got an error message signaling that I
reach the heap size limit of LWPE and after 2 or 3 seconds the
application quits.

- these aberrations have very variable density and seems to appear
only after some delay.

- with a sleep interval of 10ms the aberrations are less frequent but
still appear (I got the first after maybe 1 or 2 minutes)

- if the loop is encapsulated in a function an compiled,  the
aberrations doesn't appear (at least for a reasonable observable
period). But this is for the simplified test version witch does
nothing, because in my codes (where the activity inside each iteration
is naturally much bigger) the scheduler is compiled and produces
aberrations anyway


I join the codes for this test below

An additionnal and optional question is : if this loop overflows the
heap, how is it possible while it really does nothing but getting a
clock from the host system ?

The test is based on a specific Mac API, but in any case, any ideas or
comments will be greatly appreciated

Thanks by advance

Denis


(in-package :cl-user)

(fli:register-module :System
                 :real-name "/System/Library/Frameworks/System.framework/System"
                 :connection-style :immediate)


(fli:define-c-typedef Uint64 (:unsigned :long :long))
(fli:define-c-typedef Uint32 (:unsigned :long))
(fli:define-c-typedef Sint32 (:signed :long))

(fli:define-c-struct mach_timebase_info
  (num Uint32)
  (den Uint32))


(fli:define-foreign-function (mach_timebase_info "mach_timebase_info")
((info (:ptr mach_timebase_info)))
  :module :system
  :result-type Sint32)

(fli:define-foreign-function (mach_wait_until "mach_wait_until") ((time UInt64))
  :module :system
  :result-type Sint32)

(fli:define-foreign-function (mach_absolute_time "mach_absolute_time") ()
  :module :system
  :result-type Uint64)

(defvar *timeMachRatio* (fli:with-dynamic-foreign-objects ((timeBase
mach_timebase_info))
                          (let ((result (mach_timebase_info
timeBase)))
                            (if (zerop result)
                              (/ (fli:foreign-slot-value timeBase
'num) (fli:foreign-slot-value timeBase 'den))
                              (error (format nil "mach_timebase_info
error ~d" result))))))


(defparameter *run* t)


#|

THE TEST :

(loop while *run*
      with prev
      with oneMSMach = (round 1000000 *timeMachRatio*) ;one ms in host
time ticks
      for now = (mach_absolute_time) ;get the current host time

      ;the debbuging test
      when (and prev (< now prev)) do (print (list now prev))

      do
      (mach_wait_until (+ now oneMSMach)) ;sleep for one ms
      (setf prev now)) ;<==== evaluate to start the test


(setf *run* nil) ;<==== evaluate to stop the test
|#


FW: aberrations in a scheduler loop

After some other tests I observed in the activity monitor of the Mac that
the loop described in my message cause the real memory used  by the
application to increase more and more - in LW as in LWPE, and even on my
intel iMac... The reaction is simply more visible in LWPE because of the
size limitation of the heap. After the loop is stopped the memory size do
not decrease.

I also read on the manual that the approach of the heap size limit makes the
system unstable. So I suppose it is the explanation of the strange behavior
I've got.

It seems that the value returned by the mac API I use to get the host time
(mach_absolute_time) is not garbage collected. Is it the normal behavior ?
And, in this case, is it a way to force the application to free this memory
?

Thanks for any help

Denis

-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@gmail.com
-------------------------------------------------------





FW: aberrations in a scheduler loop

Hello,

>the loop described in my message cause the real memory used  by the
>application to increase more and more - in LW as in LWPE, and even on my
>intel iMac...

Yes but, in fact, the application grows irreversibly only if the code is not
compiled... Witch is probably normal. I turn around...

*****

On this G5 machine, I observed something witch is also linked to the use of
the (:unsigned :long :long) c-type, and fortunately really simpler to test.
I will be very grateful, if some Mac PowerPC user can test this and confirm
my observation : 

The code below, evaluated on a powerPC (at least on this G5...), returns a
value witch is too big. Called several times the value returned increases
abnormally on each call. Finally the calls return always the max 64bits
value (1- (expt 2 64))

(defvar *CoreAudio*
  (fli:register-module :CoreAudio
                   :real-name
"/System/Library/Frameworks/CoreAudio.framework/CoreAudio"
                   :connection-style :immediate))

(fli:define-c-typedef Uint64 (:unsigned :long :long))


;return the host time.

(fli:define-foreign-function (AudioGetCurrentHostTime
"AudioGetCurrentHostTime") ()
  :module :coreAudio
  :result-type Uint64)

;convert the host time in nanoseconds.

(fli:define-foreign-function (AudioConvertHostTimeToNanos
"AudioConvertHostTimeToNanos") ((hostTime Uint64))
  :module :coreAudio
  :result-type Uint64)

(let ((time (AudioGetCurrentHostTime)))
  (AudioConvertHostTimeToNanos time)) ;<======= the test


Thanks by advance

Denis


      
-------------------------------------------------------
Denis Pousseur
70 rue de Wansijn
1180 Bruxelles, Belgique

Tel : 32 (0)2 219 31 09
Mail :  denis.pousseur@gmail.com
-------------------------------------------------------
  



Updated at: 2020-12-10 08:44 UTC