Peter writes:
> I want to log the cpu-time spend searching a data base.
> I looked at the PROCTIME intrinsic, but this will only tell me
> how much CPU time is spend in the current process. In this case
> the user-interface is launching sub processes to do the searches.
Here's how I obtain the CPU time for a job/session ... note that it
uses one AIF routine and one internal routine (get_proc_cpu_time), and that
it is not complete as shown (I omitted the get_pin_tree_cpu routine,
but provided a high-level description of how to write one...
Sorry, but that's the best compromise I can do between help and income.
Nevertheless, it should suffice to allow implementation of what you
desire.
NOTE: get_proc_cpu_time is an MPE internal routine .. and, as such, is
subject to change. There may be an equivalent AIF routine that you could
call instead. get_proc_cpu_time has been in MPE since at least 1.0 (I
wrote it.)
<<-------------------------------------------------------------------
Notes for non-SPLash! programmers:
double = 32 bit signed integer
integer = 16 bit signed integer
logical = 16 bit unsigned integer
long = 64 bit real (used here as a method of easily manipulating
64-bit addresses as non-pointers)
---------------------------------------------------------------------
get_pin_tree_cpu, referred to in get_job_cpu below, is a routine of mine
that adds the CPU time for every process in a process tree (including the
"top" process (the one you pass into it). This routine could be
implemented by calling PROCINFO (item # 7) on the "top" pin (the
CI in the case of get_job_cpu), and then using the get_pin_cpu
routine for each process returned by PROCINFO. get_pin_cpu isn't trivial,
so I included it below.
--------------------------------------------------------------------->>
double procedure get_job_cpu (status, priv_controls, jsnum, alive_too);
value jsnum, alive_too;
logical jsnum, alive_too;
double status;
double array priv_controls;
option privileged, nocc;
<<------------------------------------------------------------
Purpose:
Returns CPU time that a job has used.
NOTE: the aifjsget routine does *NOT* include the CPU time
used by processes that are still alive!
If the alive_too parameter is true, then the value will
include the CPU time of all the living processes, as well
as processes that have already terminated.
Method: get CPU for dead processes (via aifjsget), and then
walk the tree of living processes (starting at the CI) and
add up their CPU time, add result to the aifjsget value.
Limitations:
get_pcl is not used, so a process could terminate between the
aifjsget and the process-tree walk, and therefore have its
CPU time go uncounted by this routine. Workaround would be
to call aifjsget a second time, and if different, redo the
process walk (until the aifjsget returns the same value twice
in a row).
Note: get_pcl cannot be used due to a design flaw in the
implementation of aifjsget.
------------------------------------------------------------>>
begin
fullvirtual pointer
ptr; ! 64 bits
long
ptr_z = ptr; ! 64 bits
long array
items (0 : 2); ! 3 * 64 bits
double array
itemerrs (0 : 2),
itemnums (0 : 2);
double
billed_cpu := 0,
ci_pin := 0,
numpins := 0,
jsnum_rec := 0,
tree_cpu := 0;
logical
jsnum_rec_1 = jsnum_rec, ! upper 16 bits of jsnum_rec
jsnum_rec_2 = jsnum_rec + 1; ! lower 16 bits of jsnum_rec
intrinsic (aifintr.pub.sys)
aifjsget;
get_job_cpu := 0;
status := 0;
itemerrs (0) :=0;
! build items...
itemnums (0) := 1028; ! get CPU count (for dead procs)
itemnums (1) := 1018; ! get CI pin (for alive_too)
itemnums (2) := 0; ! stopper
@ptr := @billed_cpu;
items (0) := ptr_z; ! set first 64 bits to the
! 64-bit virt addr of billed_cpu
@ptr := @ci_pin; ! set second 64 bits of items to
items (1) := ptr_z; ! the 64-bit virt addr of ci_pin
! call aifjsget... REQUIRES THAT YOU ARE IN PRIV MODE!
jsnum_rec_1 := jsnum;
jsnum_rec_2 := 0;
aifjsget (status, itemnums, items, itemerrs, jsnum_rec, 0, aif_id);
if status <> 0 then
begin ! failed...
if itemerrs (0) <> 0 then
status := itemerrs (0)
else if itemerrs (1) <> 0 then
status := itemerrs (1);
go end_proc;
end;
if alive_too then
begin
if ci_pin = 0 then ! did we fail to determine it?
begin
status := -2;
go end_proc;
end;
if get_pin_tree_cpu (priv_controls, ci_pin, tree_cpu, numpins)
= false then
;
end;
get_job_cpu := billed_cpu + tree_cpu;
end_proc:
end <<get_job_cpu proc>>;
<<*************************************************************>>
double procedure get_pin_cpu (pin); ! NOTE: assumes pin is in valid range!
value pin;
double pin;
option privileged, nocc;
begin
long
cputime_z; ! 64 bits
double
cputime_1 = cputime_z, ! high 32 bits
cputime_2 = cputime_z + 2; ! low 32 bits
long Procedure get_proc_cpu_time (pin); ! MPE internal
value pin;
double pin;
option external, native, nocc;
! Internal MPE XL cpu is in micro seconds.
cputime_z := get_proc_cpu_time (pin);
! Note: if cputime_z > 546 hours, then in milliseconds it
! will overflow 2**31-1 ! ...so we check for this case (obscurely)
! and return a big number of milliseconds if the overflow happens...
! the best we can do for a very unlikely event, without adding extra
! error returning parameters.
!
! SPLash! lacks 64-bit integer arithmetic, so we call a helper
! routine (written in Pascal/iX) to divide a 64-bit integer by a
! 32 bit integer, and thereby obtain CPU milliseconds...
if cputime_1 >= $1f3 d then ! SS 921117
get_pin_cpu := 2147000000 d ! SS 921117
else
get_pin_cpu := div64_32_32 (cputime_z, 1000d);
end <<get_pin_cpu proc>>;
<<*****************************************************************>>
--
Stan Sieler [log in to unmask]
http://www.allegro.com/sieler.html
|