english
version "1.0"
identify "xyz"

#: Copyright (c) 1994-2005 by Wayne C. Gramlich.
#, All rights reserved.

module timer

#: The system module provides a way of measuring program performance
#, via a set of hiearchical timers.
#,
#, This module is used by creating a single {timers} object at the
#, beginning of program execution and then building a nested set
#, of {timer} objects off of that.  At any one time only one {timer}
#, object is collecting time.  At the end of program execution,
#, {dump}@{timers}() is called to show where all of the program
#, time was spent.

define timer			#: One performance timer
    record
	child_nanoseconds unsigned #: Children nanoseconds
	child_seconds unsigned	#: Children seconds
	count unsigned		#: Number of times timer is used
	hash unsigned		#: Hash of {title}
	nanoseconds unsigned	#: Total nanoseconds
	parent timer		#: Parent timer or ??
	seconds unsigned	#: Total seconds
	subtimers vector[timer]	#: Sub-{timers} of this one
	timers timers		#: {timers} object containing this {timer}
	title string		#: Title of timer
    generate allocate, erase, print

define timers			#: A collection of performance timers
    record
	current timer		#: Current {timer} (only one active at a time)
	debug logical		#: {true} print debugging information
	disabled logical	#: {true} do not do any timing
	out_stream out_stream	#: All timer information is output here
	program_name string	#: Program name
	stack vector[timer]	#: Stack of timers
	time time		#: {time} object for high resolution time.
	top timer		#: Top level timer for entire program
    generate allocate, erase, print



#: {timers} procedures:

procedure xcreate@timers
    takes
	program_name string
	out_stream out_stream
    returns timers

    #: This procedure will create and return a new {timers} object
    #, with a name of {program_name} and an output stream of {out_stream}.


procedure create@timers
    takes
	program_name string
	out_stream out_stream
    returns timers

    #: This procedure will create and return a new {timers} object
    #, with a name of {program_name} and an output stream of {out_stream}.

    #: Return the result:

procedure dump@timers
    takes
	timers timers
	out_stream out_stream
    returns_nothing

    #: This procudure will output the timer values associated with each
    #, {timer} in {timers} to {out_stream}.


#: {timer} procedures:

procedure create@timer
    takes
	parent timer
	timers timers
	title string
    returns timer

    #: This procedure creates and returns an initialized {timer} object
    #, associated with {timers{ with a title of {title} and a parent
    #, of {parent}.  The top-most timer is accessed via {timer}.{top}.
    #, Time collection is enabled with {enable}@({timer}.{top})


procedure child_create@timer
    takes
	parent timer
	title string
    returns timer

    #: This procedure will create and return a child {timer} object
    #, whose parent timer is {parent} and whose title on output
    #, is {title}.


procedure child_once@timer
    takes
	parent timer
	title string
    returns timer

    #: This procedure will search through {parent} looking for
    #, a child timer with a title of {title} and return it;
    #, if now matching child timer is found, one is created
    #, and returned.  The returned timer is not set to be the
    #, current one.


procedure child_next@timer
    takes
	parent timer
	title string
    returns timer

    #: This procedure will get the child timer named {title} from {parent}
    #, (or create it if it does not exist), make it the current timer,
    #, and return it.


procedure child_create_current@timer
    takes
	parent timer
	title string
    returns timer

    #: This procedure will create and return a child {timer} object
    #, whose parent timer is {parent} and whose title on output
    #, is {title}.  The returned {timer} is set to the current timer.


procedure current_set@timer
    takes
	timer timer
    returns_nothing

    #: This procedure will make {timer} the current timer.


procedure disable@timer
    takes
	timer timer
    returns_nothing

    #: This procedure will disable all timers.  {timer} is used to
    #, access the {timers} object.


procedure enable@timer
    takes
	timer timer
    returns_nothing

    #: This procedure will enable all timers.  {timer} is used to
    #, access the {timers} object.


procedure push@timer
    takes
	timer timer
    returns_nothing

    #: This procedure will make {timer} be current.  The previous
    #, timer is pushed onto a stack for subsequenter poping.


procedure pop@timer
    takes
	timer timer
    returns_nothing

    #: This procedure will restore the previous timer.  {timer} is only
    #, used to access the timer stack.


procedure dump@timer
    takes
	timer timer
	level unsigned
	out_stream out_stream
    returns_nothing

    #: This procedure will output {timer} to {out_stream} indented by {level}.


procedure sum@timer
    takes
	timer timer
    returns_nothing

    #: This procedure will fill in the total time used by {timer}'s children.