/****************************************/ /* */ /* Author: */ /* */ /* Ira Winston */ /* Computer Science Department */ /* University of Pennsylvania */ /* */ /****************************************/ Add_to_Index: Procedure(indextree,timestamp,count) Recursive; Declare indextree Pointer, timestamp Bit(64) Aligned, count Fixed Binary(31); Declare Null Builtin; %Include indexdef; %Include Critical_Section; %Include Time_Less; /* Add a node to the sorted tree 'indextree' with value 'timestamp' */ If indextree = Null Then Do; Call Start_Critical_Section; Allocate index_entry Set(indextree); indextree->index_entry.left = Null; indextree->index_entry.right = Null; Call End_Critical_Section; indextree->index_entry.timestamp = timestamp; count = count + 1; End; Else If time_less(timestamp,indextree->index_entry.timestamp) Then Call Add_to_Index(indextree->index_entry.left,timestamp,count); Else Call Add_to_Index(indextree->index_entry.right,timestamp,count); End Add_to_Index; Locked_record: Procedure(retries,error_code) Returns(Bit(1)); Declare retries Fixed Binary, /* Number of retries so far */ error_code Fixed Binary; /* Current error code */ Declare time Bit(64) Aligned, milliseconds(2) Fixed Binary(31) Based(Addr(time)); Declare RMS$_RLK Fixed Binary(31) Globalref Value; %Include Sys$Schdwk; %Include $Stsdef; %Include Sys$Hiber; If error_code ^= RMS$_RLK Then Return('0'b); retries = retries + 1; If retries > 20 Then Do; Put Skip List('?Record locked after 20 retries'); Return('0'b); End; Put Skip Edit('Retry ',retries) (A,F(3)); milliseconds(1) = -2500000*retries; /* 250 ms * retries */ milliseconds(2) = -1; Sts$Value = Sys$schdwk(,,time,); Sts$Value = Sys$hiber(); Return('1'b); End locked_record; Read_Line: Procedure (prompt,input_buffer,convert) Returns(Bit(1)); %Include Critical_Section; %Include Upper_case; Declare prompt Character(*), input_buffer Character(255) Varying, convert Bit(1); Declare first_read Bit(1) Static Init('1'b); Declare RMS$_TNS Fixed Binary(31) Globalref Value; On Endfile(Sysin) Goto Endfile_sysin; If first_read Then Do; On Error Begin; If Oncode() = RMS$_TNS Then Do; Put Skip List('?Line too long. Re-enter.'); Goto Retry1; End; Else Call Resignal(); End; Retry1: Put Skip; Get Edit(input_buffer) (A(255)) Options(Prompt(prompt)); Revert Error; first_read = '0'b; End; Else Do; On Error Begin; If Oncode() = RMS$_TNS Then Do; Put Skip List('?Line too long. Re-enter.'); Goto Retry2; End; Else Call Resignal(); End; Retry2: Get Skip Edit(input_buffer) (A(255)) Options(Prompt(prompt)); Revert Error; End; If convert Then input_buffer = Upper_case((input_buffer)); Return('1'b); Endfile_sysin: Call Start_Critical_Section; first_read = '1'b; Close File(Sysin); Open File(Sysin); Call End_Critical_Section; Return('0'b); End Read_Line; Scan_index: Procedure (indextree,action_routine,count) Recursive; Declare indextree Pointer, Action_routine Entry(pointer,Fixed Binary(31)), count Fixed Binary(31), save_right Pointer; %Include indexdef; If indextree ^= Null() Then Do; Call Scan_index(indextree->index_entry.left,action_routine,count); save_right = indextree->index_entry.right; /* In case action is free */ count = count + 1; Call Action_routine(indextree,count); Call Scan_index(save_right,action_routine,count); End; End Scan_index; Time_less: Procedure(time1,time2) Returns(Bit(1)); Declare (time1,time2) Bit(64) Aligned; Declare time1_character Character(8) Based(Addr(time1)), time2_character Character(8) Based(Addr(time2)), (time1_rev,time2_rev) Character(8), i Fixed Binary; Do i = 1 to 8; Substr(time1_rev,9-i,1) = Substr(time1_character,i,1); Substr(time2_rev,9-i,1) = Substr(time2_character,i,1); End; Return (time1_rev < time2_rev); End Time_less; Start_Critical_Section: Procedure; %Include Sys$Setast; %Include $Stsdef; Declare ref_count Fixed Binary Static Initial(0); If ref_count = 0 Then Sts$Value = Sys$Setast(0); ref_count = ref_count + 1; Return; End_Critical_Section: Entry; ref_count = ref_count - 1; If ref_count = 0 Then Sts$Value = Sys$Setast(1); Else If ref_count < 0 Then Put Skip List('Too many calls to End_Critical_Section'); Return; End Start_Critical_Section; Upper_case: Procedure (string) Returns (character(*)); Declare string Character(*); Return(Translate(string,'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')); End Upper_case;