I've come to the conclusion that an alarm can't be configured to fire a predicate periodically, or at least not automatically. Although one of the options in alarm/4
is remove(false)
, one has to call uninstall_alarm/1
and install_alarm/1
in order to restart the time counter. Not doing so and not calling remove_alarm/1
, will produce a resource leak, which will probably be protected somehow and might eventually stop the actual timer.
This would be the proper way to use periodic calls to predicates stat_mem/0
and stat_cpu/0
:
stat_start(Id,T) :-
alarm(T,stat_point(Id,T),Id,[remove(false),install(true)]).
stat_point(Id,T) :-
uninstall_alarm(Id),
install_alarm(Id,T),
stat_mem,
stat_cpu.
Note that in this case a call to install_alarm/2
is needed instead of /1
. If we don't do that, the time is set to 0 and the alarm will fire the predicate continuously.
Now, more related to the 'determinism' issue of my initial question, I just can say that although my stat_point
inserts uncertainty to my time and (less likely) memory measurements, this uncertainty is ultimately determined by the statistics/2
predicate. Since CPU time is affected by this call, the solution suggested by magus --use a "primary standard" sample to find the offset of my measurements-- might be an approach toward reducing this uncertainty.
In fact, since the memory used and execution times were already far greater than those produced by repeated calls to statistics/2
the accuracy of my measurements is "relatively" small.