ARPDAS_QNX6 1.0
|
00001 #include <stdlib.h> 00002 #include "nortlib.h" 00003 #include "tma.h" 00004 char rcsid_tmaR2_c[] = 00005 "$Header: /cvsroot/arp-das/QNX6/tmlib/src/tmaR2.c,v 1.3 2009/11/18 20:46:18 ntallen Exp $"; 00006 00007 void tma_init_state( int partno, tma_state *cmds, const char *name ) { 00008 tma_prtn *p; 00009 00010 if ( partno < tma_n_partitions ) { 00011 /* tma_new_state() sets part basetime, outputs STATETIME 00012 Does *not* set RUNTIME or NEXTTIME or next command area 00013 basetime is set only if tma_basetime is non-zero (set 00014 in tma_process first time after TM starts). lastcheck is 00015 set to basetime. partno, name ); 00016 */ 00017 tma_new_state( partno, name ); 00018 p = &tma_partitions[partno]; 00019 p->cmds = cmds; 00020 p->next_cmd = 0; 00021 p->waiting = 0; 00022 p->lastcheck = p->basetime - 1; 00023 if ( p->basetime == 0L && p->cmds != 0 ) { 00024 /* Issue start-up commands (T==0, ">") */ 00025 for (;;) { 00026 cmds = &p->cmds[p->next_cmd]; 00027 if ( cmds->dt != 0 || cmds->cmd[0] != '>' ) 00028 break; 00029 p->next_cmd++; 00030 if ( cmds->cmd[1] == '_' ) ci_sendcmd(cmds->cmd+2, 2); 00031 else ci_sendcmd(cmds->cmd+1, 0); 00032 } 00033 } 00034 } 00035 } 00036 00037 /* tma_process returns 0 when no more action is required for any 00038 partition at the present time (now). Otherwise it returns 00039 a positive integer which is an index into case statement 00040 generated by tmcalgo for validating states. */ 00041 int tma_process( long int now ) { 00042 int partno, success, state_case, Rpartno; 00043 tma_prtn *p; 00044 long int dt, pdt, timeout, lastcheck; 00045 const char *cmd; 00046 00047 if (tma_runbasetime == 0L) { 00048 unsigned int i; 00049 00050 tma_runbasetime = now; 00051 for (i = 0; i < tma_n_partitions; i++) { 00052 tma_partitions[i].basetime = now; 00053 tma_partitions[i].lastcheck = now-1; 00054 } 00055 } 00056 for ( partno = 0; partno < tma_n_partitions; partno++ ) { 00057 p = &tma_partitions[ partno ]; 00058 if ( now != p->lastcheck ) { 00059 lastcheck = p->lastcheck; 00060 if ( lastcheck < p->basetime ) 00061 lastcheck = p->basetime; 00062 if ( p->waiting > 0 ) { 00063 dt = now - lastcheck; 00064 if ( dt >= p->waiting ) { 00065 p->waiting = 0; 00066 p->next_cmd++; 00067 } 00068 } 00069 if ( p->waiting == 0 && tma_is_holding == 0 ) { 00070 dt = now - p->basetime; 00071 if ( p->cmds != 0 && p->next_cmd >= 0 ) { 00072 while ( p->waiting == 0 ) { 00073 pdt = p->cmds[p->next_cmd].dt; 00074 cmd = p->cmds[p->next_cmd].cmd; 00075 if ( pdt == -1 ) { 00076 p->next_cmd = -1; 00077 p->nexttime = 0; 00078 break; 00079 } else if ( pdt > dt ) { 00080 if ( p->nexttime != pdt ) { 00081 p->nexttime = pdt; 00082 if ( ( p->next_str == 0 || *p->next_str == '\0' ) 00083 && *cmd == '>' ) 00084 p->next_str = cmd+1; 00085 } 00086 break; 00087 } else { 00088 p->next_cmd++; 00089 switch( *cmd ) { 00090 case '>': 00091 if ( cmd[1] == '_' ) 00092 ci_sendcmd(cmd+2, 2); 00093 else 00094 ci_sendcmd(cmd+1, 0); 00095 p->next_str = ""; 00096 break; 00097 case '"': 00098 p->next_str = cmd; 00099 break; 00100 case '#': 00101 return atoi( cmd+1 ); 00102 case '?': 00103 if ( sscanf( cmd+1, "%d,%ld,%d", 00104 &success, &timeout, &state_case ) != 3 ) 00105 nl_error( 4, "Error reading hold command\n" ); 00106 if ( timeout > 0 ) 00107 timeout += pdt + p->basetime - lastcheck; 00108 p->waiting = timeout; 00109 p->next_cmd--; 00110 if ( state_case > 0 ) return state_case; 00111 break; 00112 case 'R': 00113 if ( sscanf( cmd+1, "%d,%d", &Rpartno, 00114 &state_case ) != 2 ) 00115 nl_error( 4, "Error reading Resume command\n" ); 00116 tma_succeed( Rpartno, -state_case ); 00117 if ( Rpartno < partno ) return -1; 00118 break; 00119 default: 00120 nl_error( 1, "Unknown cmd char %c in tma_process", *cmd ); 00121 } 00122 } 00123 } 00124 } 00125 } 00126 } 00127 } 00128 for ( partno = 0; partno < tma_n_partitions; partno++ ) { 00129 p = &tma_partitions[ partno ]; 00130 lastcheck = p->lastcheck; 00131 if ( lastcheck < p->basetime ) 00132 lastcheck = p->basetime; 00133 dt = now - lastcheck; 00134 if ( dt != 0 ) { 00135 if ( p->waiting != 0 || tma_is_holding != 0 ) { 00136 p->basetime += dt; 00137 if ( p->waiting > dt ) { 00138 p->waiting -= dt; 00139 } else if ( p->waiting > 0 ) 00140 p->waiting = 0; 00141 } 00142 } 00143 if ( now != p->lastcheck ) { 00144 p->lastcheck = now; 00145 if ( p->row >= 0 ) { 00146 if ( p->next_str != 0 ) { 00147 tma_next_cmd( partno, p->next_str ); 00148 p->next_str = NULL; 00149 } 00150 tma_time( p, RUNTIME_COL, now - tma_runbasetime ); 00151 tma_time( p, STATETIME_COL, now - p->basetime ); 00152 pdt = p->nexttime; 00153 switch ( pdt ) { 00154 case -1: continue; 00155 case 0: 00156 pdt = 0; 00157 p->nexttime = -1; 00158 break; 00159 default: 00160 pdt += p->basetime - now; 00161 break; 00162 } 00163 tma_time( p, NEXTTIME_COL, pdt ); 00164 } 00165 } 00166 } 00167 return 0; /* Nothing left to do */ 00168 } 00169 00170 void tma_succeed( int partno, int statecase ) { 00171 tma_prtn *p; 00172 int success, state_case, res_case; 00173 long int timeout; 00174 const char *cmd; 00175 00176 if ( partno < 0 || partno >= tma_n_partitions ) 00177 nl_error( 4, "Invalid partno in tma_succeed" ); 00178 p = &tma_partitions[ partno ]; 00179 if ( p->cmds != 0 && p->next_cmd >= 0 ) { 00180 cmd = p->cmds[p->next_cmd].cmd; 00181 if ( cmd != 0 && *cmd == '?' ) { 00182 int n_args = sscanf( cmd+1, "%d,%ld,%d,%d", 00183 &success, &timeout, &state_case, &res_case ); 00184 if ( n_args < 3 ) nl_error( 4, "Error re-reading hold command\n" ); 00185 if ( statecase > 0 && state_case != statecase ) 00186 nl_error( 1, "Different statecase active in tma_succeed" ); 00187 else if ( statecase < 0 && 00188 ( n_args < 4 || -statecase != res_case) ) { 00189 if ( n_args < 4 ) 00190 nl_error( 1, "Resume not compatible with this version" ); 00191 else 00192 nl_error( -3, "Resume(%d,%d): other state is holding", partno, 00193 -statecase ); 00194 } else { 00195 p->waiting = 0; 00196 p->next_cmd += success; 00197 } 00198 return; 00199 } 00200 } 00201 if ( statecase < 0 ) 00202 nl_error( -3, "Resume(%d,%d): Specified state not holding", 00203 partno, -statecase ); 00204 else nl_error( -3, "Hold(%d,%d) not active in tma_succeed", 00205 partno, statecase ); 00206 } 00207 00208 /* 00209 =Name <funcname>: <Description> 00210 =Name tma_init_state(): Initialize a new TMA state 00211 =Subject TMA Internal 00212 =Name tma_process(): Execute TMA commands 00213 =Subject TMA Internal 00214 =Name tma_succeed(): End TMA Hold states 00215 =Subject TMA Internal 00216 =Synopsis 00217 #include "tma.h" 00218 void tma_init_state( int partno, tma_state *cmds, char *name ); 00219 int tma_process( long int now ); 00220 void tma_succeed( int partno, int statecase ); 00221 00222 =Description 00223 00224 These are support functions for TMCALGO algorithms. They are 00225 called from the .tmc code which TMCALGO generates. Users should 00226 not need to call these functions directly. 00227 00228 tma_init_state() is called to when a TMA state is validated. 00229 It is responsible for initializing the status lines and setting 00230 up the internal structures which keep track of the current 00231 position within the algorithm. 00232 00233 tma_process() is called every second to execute algorithm 00234 commands. Its single argument is the "current" data stream 00235 time. (This will be very close to the current time when 00236 running an algorithm in realtime, but during playback, it will 00237 be the time when the data was taken.) 00238 00239 tma_succeed() is called to release a partition from a HOLD 00240 state. If statecase is greater than zero, it must match 00241 the third argument of the currently pending hold command. 00242 This form is generated by "Hold until" syntaxes. If statecase 00243 is less than zero, it must equal (but negative) to the fourth 00244 argument. This form is generated by the "Resume" statement. 00245 00246 =Returns 00247 00248 tma_process() returns zero if there is no more work to be done at 00249 this time. If it returns a non-zero value, the TMCALGO-generated 00250 .tmc program uses the value in a switch statement to select a 00251 state to validate. (This value is referred to as a "state_case" 00252 within the tmcalgo source code.) A return value of -1 indicates 00253 that work is not completed, but no action is required by the 00254 caller other than to call tma_process() again. This is necessary 00255 when a "Resume" command is executed, which may unblock a 00256 partition that has already been passed over. 00257 00258 tma_init_state() and tma_succeed() have void returns. 00259 00260 =SeeAlso 00261 00262 =TMA Internal= functions. 00263 00264 =End 00265 */