-- t000008.ada -- PERFORMANCE MEASUREMENT : Measure the average time to pass an integer -- from a producer task through a buffer task -- to a consumer task package TASK_PACK_8 is task type BUFFER_TYPE is entry TAKE_ITEM ( ITEM : in INTEGER ) ; entry GIVE_ITEM ( ITEM : out INTEGER ) ; end BUFFER_TYPE ; task type PRODUCER_TYPE is entry PRODUCE ( COUNT : in NATURAL ) ; end PRODUCER_TYPE ; task type CONSUMER_TYPE is entry CONSUME ( COUNT : in NATURAL ) ; entry WAIT_FOR_CONSUMER_COMPLETION ( CHECK : out NATURAL ) ; end CONSUMER_TYPE ; BUFFER_TASK : BUFFER_TYPE ; end TASK_PACK_8 ; with TASK_PACK_8 ; use TASK_PACK_8 ; with BREAK ; use BREAK ; -- control optimization with ITERATION ; -- obtain stable measurement with PIWG_IO ; -- output results procedure T000008 is -- main procedure to execute CPU_TIME : DURATION ; -- CPU time for one feature execution CPU_TOL : DURATION ; -- tolerance on measurement WALL_TIME : DURATION ; -- WALL time for one feature execution SCALE : ITERATION.SCALE := ITERATION.MICROSECONDS ; -- units CHECK_TIMES : constant := 100 ; -- inside loop count and check ITERATION_COUNT : INTEGER ; -- set and varied by ITERATION package STABLE : BOOLEAN ; -- true when measurement stable -- -- More declarations -- P : PRODUCER_TYPE ; C : CONSUMER_TYPE ; begin ITERATION.START_CONTROL ; -- dummy to bring in pages on some machines delay 0.5 ; -- wait for stable enviornment on some machines ITERATION.INITIALIZE ( ITERATION_COUNT ) ; loop -- until stable measurement, ITERATION_COUNT increases each time -- -- Control loop -- ITERATION.START_CONTROL ; for J in 1 .. ITERATION_COUNT loop GLOBAL := 0 ; for INSIDE_LOOP in 1 .. CHECK_TIMES loop ITERATION.INCREMENT ( GLOBAL ) ; -- loop overhead and counter increment end loop ; end loop ; ITERATION.STOP_CONTROL ( GLOBAL , CHECK_TIMES ) ; -- -- Test loop -- ITERATION.START_TEST ; for J in 1 .. ITERATION_COUNT loop GLOBAL := 0 ; -- for INSIDE_LOOP in 1 .. CHECK_TIMES loop -- performed in producer -- end loop ; P.PRODUCE ( CHECK_TIMES ) ; C.CONSUME ( CHECK_TIMES ) ; C.WAIT_FOR_CONSUMER_COMPLETION ( GLOBAL ) ; -- check built in here end loop ; ITERATION.STOP_TEST ( GLOBAL , CHECK_TIMES ) ; ITERATION.TEST_STABLE ( ITERATION_COUNT , STABLE ) ; exit when STABLE ; end loop ; -- ITERATION.FEATURE_TIMES ( CPU_TIME , CPU_TOL , WALL_TIME , SCALE ) ; -- -- Printout -- PIWG_IO.PIWG_OUTPUT ( "T000008" , "Tasking" , CPU_TIME , CPU_TOL , WALL_TIME , SCALE , ITERATION_COUNT * CHECK_TIMES , " Measure the average time to pass an integer " , " from a producer task through a buffer task " , " to a consumer task " ) ; abort BUFFER_TASK ; -- get rid of tasks abort C ; abort P ; end T000008 ; package body TASK_PACK_8 is task body BUFFER_TYPE is type BUFFER_RANGE is range 0..20 ; subtype BUFFER_INDEX is BUFFER_RANGE range 1..BUFFER_RANGE'LAST ; BUFFER : array ( BUFFER_INDEX ) of INTEGER ; HEAD, TAIL : BUFFER_INDEX := BUFFER_INDEX'FIRST ; BUFFER_COUNT : BUFFER_RANGE := 0 ; begin loop select when BUFFER_COUNT < BUFFER_RANGE'LAST => accept TAKE_ITEM ( ITEM : in INTEGER ) do BUFFER ( HEAD ) := ITEM ; HEAD := ( HEAD mod BUFFER_RANGE'LAST ) + 1 ; BUFFER_COUNT := BUFFER_COUNT + 1 ; end TAKE_ITEM ; or when BUFFER_COUNT > 0 => accept GIVE_ITEM ( ITEM : out INTEGER ) do ITEM := BUFFER ( TAIL ) ; TAIL := ( TAIL mod BUFFER_RANGE'LAST ) + 1 ; BUFFER_COUNT := BUFFER_COUNT - 1 ; end GIVE_ITEM ; end select ; end loop ; end BUFFER_TYPE ; task body PRODUCER_TYPE is NUMBER_TO_PRODUCE : NATURAL ; begin loop accept PRODUCE ( COUNT : in NATURAL ) do NUMBER_TO_PRODUCE := COUNT ; end PRODUCE ; for I in 1..NUMBER_TO_PRODUCE loop BUFFER_TASK.TAKE_ITEM ( I ) ; end loop ; end loop ; end PRODUCER_TYPE ; task body CONSUMER_TYPE is NUMBER_TO_CONSUME : NATURAL ; COUNT_CHECK : NATURAL := 0 ; ITEM : INTEGER ; begin loop accept CONSUME ( COUNT : in NATURAL ) do NUMBER_TO_CONSUME := COUNT ; end CONSUME ; for I in 1..NUMBER_TO_CONSUME loop BUFFER_TASK.GIVE_ITEM ( ITEM ) ; COUNT_CHECK := COUNT_CHECK + 1 ; end loop ; accept WAIT_FOR_CONSUMER_COMPLETION ( CHECK : out NATURAL ) do CHECK := COUNT_CHECK ; COUNT_CHECK := 0 ; -- ready for next use end WAIT_FOR_CONSUMER_COMPLETION ; end loop ; end CONSUMER_TYPE ; end TASK_PACK_8 ;