OpenVMS Source Code Demos
TWO_TIMER_DEMO.BAS
1000 %title "two_timer_demo_xxx" !
%ident "version_101.1" ! <<<---+
declare string constant k_version = "101.1" , ! <<<---+ &
k_program = "two_timer_demo" !
!=======================================================================
! title : timer_demo_xxx.bas
! author : Neil Rieck ( https://neilrieck.net/ )
! created: 2004.01.01
!=======================================================================
option type = explicit ! no kid stuff...
set no prompt !
!
! system declarations
!
%include "starlet" %from %library "sys$library:basic$starlet" ! system services
%include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
%include "lib$routines" %from %library "sys$library:basic$starlet" ! lib$
!
! home brewed functions
!
external long function get_timer_bit_vector(long) ! required for used with SYS$WFLOR
!
declare long rc% , ! return code &
timer_event_flag% , ! timer event flag &
timer_ef_state% , ! timer event flag state &
tcp_event_flag% , ! tcp event flag &
tcp_ef_state% , ! tcp event flag state &
mask% , ! required for sys$wflor &
junk% , ! &
basic$QuadWord DeltaQuad ! for sys$bintim etc.
!
!=======================================================================
! main
!=======================================================================
main:
margin #0, 132 ! width for the log file
print k_program +"_"+ k_version !
print string$(len(k_program +"_"+ k_version), asc("=")) ! underline (how will this optimize?)
!
! <<< get some event flags for later >>>
!
if tcp_event_flag% = 0 then ! if not yet allocated
rc% = lib$get_EF( tcp_event_flag% ) ! get an event flag
if ((rc% and 7%) <> 1) then !
print "lib$get_EF-1 rc: ";str$(rc%) !
goto rc_exit !
end if !
end if !
!
if timer_event_flag% = 0 then ! if not yet allocated
rc% = lib$get_EF( timer_event_flag% ) ! get another event flag
if ((rc% and 7%) <> 1) then !
print "lib$get_EF-2 rc: ";str$(rc%) !
goto rc_exit !
end if !
end if !
!
! <<< arm a timer to expire 'x' time from now >>>
!
print "-i- arming timer-1 (timer) for 10 seconds from now" !
declare string constant k_delay010 = "0 00:00:10" ! set delay time 10 seconds from now
rc% = sys$bintim(k_delay010, DeltaQuad ) ! init delta time ('x' time from now)
print "-e- sys$bintim rc: "+ str$(rc%) if ((rc% and 1%) <> 1%) !
rc% = sys$setimr(timer_event_flag%,DeltaQuad by ref,,,) ! now use it to schedule a wake up
print "-e- sys$setimr rc: "+ str$(rc%) if ((rc% and 1%) <> 1%) !
!
! <<< use a second timer to simulate some sort of TCP timeout >
!
print "-i- arming timer-2 (fake tcp) for 20 seconds from now" !
declare string constant k_delay020 = "0 00:00:20" ! set delay time 20 seconds from now
rc% = sys$bintim(k_delay020, DeltaQuad ) ! init delta time ('x' time from now)
print "-e- sys$bintim rc: "+ str$(rc%) if ((rc% and 1%) <> 1%) !
rc% = sys$setimr(tcp_event_flag%,DeltaQuad by ref,,,) ! now use it to schedule a wake up
print "-e- sys$setimr rc: "+ str$(rc%) if ((rc% and 1%) <> 1%) !
!
! note: for the SYS$WFLOR call to work, both event flags must be in the same event flag cluster.
! The first parameter is only used to determine which event flag cluster to test.
! The second parameter (mask) contains bits representing event flags within that cluster
!
mask% = get_timer_bit_vector( tcp_event_flag%) ! insert vector 1 into mask
mask% = mask% or get_timer_bit_vector(timer_event_flag%) ! insert vector 2 into mask
!
! <<< wait for either the 'TCP event flag' or the 'TIMER event flag' to change state >>>
!
print "-i- waiting for event flag "+ str$(tcp_event_flag%) +" or event flag "+ str$(timer_event_flag%)
!
rc% = sys$wflor( tcp_event_flag%, mask%) ! wait for a response from one of two flags
print "-e- sys$waitfr rc: "+ str$(rc%) if ((rc% and 1%) <> 1%) !
!
! <<< cancel all timer requests (if any) >>>
!
print "-i- Calling $CanTim" !
rc% = sys$cantim(,) ! cancel all timer requests
print "-e- sys$cantim rc: "+ str$(rc%) if ((rc% and 1%) <> 1%) !
!
! which event flag is set? TCP or TIMER?
!
rc% = sys$readEF(tcp_event_flag%, junk%) ! test TCP event flag
select rc% !
case SS$_WASCLR !
tcp_ef_state% = 0 !
case SS$_WASSET !
tcp_ef_state% = 1 !
case else !
print "-e- sys$readef-tcp rc: "+ str$(rc%) !
tcp_ef_state% = 0 !
end select !
print "-i- TCP EF State : ";str$(tcp_ef_state%) !
!
rc% = sys$readEF(timer_event_flag%, junk%) ! test TIMER event flag
select rc% !
case SS$_WASCLR !
timer_ef_state% = 0 !
case SS$_WASSET !
timer_ef_state% = 1 !
case else !
print "-e- sys$readef-timer rc: "+ str$(rc%) !
timer_ef_state% = 0 !
end select !
print "-i- Timer EF State: ";str$(timer_ef_state%) !
!
! at this point either the TCP-EF or the TIMER-EF should be set
!
if (timer_ef_state% = 1) and ! if the TIMER-EF is set &
( tcp_ef_state% = 0) ! and the TCP-EF is clear
then ! then something timed out
print "-i-the tcp event timed out (so do something)" !
end if !
!
! here is an alternate way to test all bits quickly
!
junk% = (timer_ef_state% * 2) + tcp_ef_state% ! produce a weighted number
select junk% !
case 0 !
print "no event flags (something went wrong)" !
case 1 !
print "tcp event only (timer event cancelled)" !
case 2 !
print "timer event only (tcp timed out)" !
case 3 !
print "both timer + tcp events (this is possible)" !
end select !
!====================================================================================================
! <<< adios... >>>
!====================================================================================================
fini:
rc% = 1 ! vms -s-
!
! rc% must be set up b4 this point (and must not be changed)
!
rc_exit:
30000 end program rc% !
!#######################################################################
!
! <<< external functions >>>
!
!======================================================================
! get timer bit vector
! (see OpenVMS system systevices documentation for "sys$wflor")
!
! notes: cluster event flags
! 0 00- 31
! 1 32- 63
! 2 64- 95
! 3 96-127
!======================================================================
31040 function long get_timer_bit_vector(long event_flag)
option type = explicit
declare long temp
!
select event_flag
case <= 31
temp = event_flag
case <= 63
temp = event_flag - 32
case <= 95
temp = event_flag - 64
case else
temp = event_flag -96
end select
!
select temp ! this code will avoid an integer overflow
case 31 ! need to set bit #31
! 33222222222211111111110000000000
! 10987654321098765432109876543210
get_timer_bit_vector = B"10000000000000000000000000000000"L ! so return this
case else !
get_timer_bit_vector = (2% ^ temp) ! else return this
end select
!
end function ! get_timer_bit_vector
!
!#######################################################################
Back to
Home
Neil Rieck
Waterloo, Ontario, Canada.