Ported ajk version from lanl
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
1.7.10
|
||||
1.8_Test
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
ENVIRONMENT: UNIX
|
||||
HISTORY:
|
||||
19nov91,ajk Changed find_var() to findVar().
|
||||
28apr92,ajk Implemented efClear() & efTestAndClear().
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include "parse.h"
|
||||
@@ -207,7 +208,7 @@ int level; /* indentation level */
|
||||
{
|
||||
Expr *epf;
|
||||
int nparams;
|
||||
extern int reent_flag;
|
||||
extern int reent_opt;
|
||||
if (ep == 0)
|
||||
return;
|
||||
|
||||
@@ -269,7 +270,7 @@ int level; /* indentation level */
|
||||
eval_expr(stmt_type, ep->left, sp, level+1);
|
||||
break;
|
||||
case E_VAR:
|
||||
if(reent_flag)
|
||||
if(reent_opt)
|
||||
{ /* Make variables point to allocated structure */
|
||||
Var *vp;
|
||||
vp = (Var *)ep->left;
|
||||
@@ -352,12 +353,14 @@ int level;
|
||||
printf("\t");
|
||||
}
|
||||
/* func_name_to_code - convert function name to a code */
|
||||
enum fcode { F_DELAY, F_EFSET, F_EFTEST, F_PVGET, F_PVPUT,
|
||||
enum fcode { F_DELAY, F_EFSET, F_EFTEST, F_EFCLEAR, F_EFTESTANDCLEAR,
|
||||
F_PVGET, F_PVPUT,
|
||||
F_PVMONITOR, F_PVSTOPMONITOR, F_PVCOUNT, F_PVINDEX,
|
||||
F_PVSTATUS, F_PVSEVERITY, F_PVFLUSH, F_PVERROR, F_PVGETCOMPLETE,
|
||||
F_PVCONNECTED, F_PVCHANNELCOUNT, F_PVCONNECTCOUNT, F_NONE };
|
||||
|
||||
char *fcode_str[] = { "delay", "efSet", "efTest", "pvGet", "pvPut",
|
||||
char *fcode_str[] = { "delay", "efSet", "efTest", "efClear", "efTestAndClear",
|
||||
"pvGet", "pvPut",
|
||||
"pvMonitor", "pvStopMonitor", "pvCount", "pvIndex",
|
||||
"pvStatus", "pvSeverity", "pvFlush", "pvError", "pvGetComplete",
|
||||
"pvConnected", "pvChannelCount", "pvConnectCount", NULL };
|
||||
@@ -377,10 +380,10 @@ char *fname;
|
||||
}
|
||||
|
||||
/* Process special function (returns TRUE if this is a special function)
|
||||
Checks for special functions:
|
||||
efSet(ef) and efGet(ef) -> set corresponding bit in ef_mask.
|
||||
pvPut() & pvGet -> replace variable with ptr to db struct.
|
||||
delay() - replaces delay time with delay index.
|
||||
Checks for one of the following special functions:
|
||||
- event flag functions
|
||||
- process variable functions
|
||||
- delay()
|
||||
*/
|
||||
special_func(stmt_type, ep, sp)
|
||||
int stmt_type; /* ACTION_STMT or EVENT_STMT */
|
||||
@@ -415,6 +418,8 @@ Expr *sp; /* current State struct */
|
||||
{
|
||||
case F_EFSET:
|
||||
case F_EFTEST:
|
||||
case F_EFCLEAR:
|
||||
case F_EFTESTANDCLEAR:
|
||||
if (vp->type != V_EVFLAG)
|
||||
{
|
||||
fprintf(stderr, "Line %d: ", ep->line_num);
|
||||
|
||||
+33
-12
@@ -7,6 +7,8 @@
|
||||
DESCRIPTION: Generate tables for run-time sequencer.
|
||||
See also: phase2.c & gen_ss_code.c
|
||||
ENVIRONMENT: UNIX
|
||||
HISTORY:
|
||||
28apr92,ajk Implemented new event flag mode.
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -84,7 +86,7 @@ int index;
|
||||
Var *vp;
|
||||
char *get_type_string, *put_type_string, *postfix;
|
||||
extern char *prog_name;
|
||||
extern int reent_flag;
|
||||
extern int reent_opt;
|
||||
int size, ev_flag, count;
|
||||
|
||||
vp = cp->var;
|
||||
@@ -138,7 +140,7 @@ int index;
|
||||
postfix = "[0]";
|
||||
else
|
||||
postfix = "";
|
||||
if (reent_flag)
|
||||
if (reent_opt)
|
||||
printf("OFFSET(struct UserVar, %s%s), ", vp->name, postfix);
|
||||
else
|
||||
printf("&%s%s, ", vp->name, postfix); /* variable ptr */
|
||||
@@ -168,7 +170,7 @@ int index;
|
||||
|
||||
printf("0, "); /* event id supplied by CA */
|
||||
|
||||
printf("0, "); /* getSemId */
|
||||
printf("0, "); /* semaphore id for async. pvGet() */
|
||||
|
||||
printf("&%s", prog_name); /* ptr to state program structure */
|
||||
|
||||
@@ -236,9 +238,10 @@ char *ss_name;
|
||||
gen_state_prog_table()
|
||||
{
|
||||
extern char *prog_name, *prog_param;
|
||||
extern int async_flag, debug_flag, reent_flag, conn_flag;
|
||||
extern int async_opt, debug_opt, reent_opt, conn_opt, newef_opt;
|
||||
extern int nstates;
|
||||
extern Expr exit_code_list;
|
||||
int i;
|
||||
|
||||
printf("\n/* Program parameter list */\n");
|
||||
|
||||
@@ -276,7 +279,7 @@ gen_state_prog_table()
|
||||
|
||||
printf("\tNULL,\t/* ptr to user area (not used) */\n");
|
||||
|
||||
if (reent_flag)
|
||||
if (reent_opt)
|
||||
printf("\tsizeof(struct UserVar),\t/* user area size */\n");
|
||||
else
|
||||
printf("\t0,\t/* user area size (not used) */\n");
|
||||
@@ -291,8 +294,13 @@ gen_state_prog_table()
|
||||
|
||||
printf("\tprog_param,\t/* *params */\n");
|
||||
|
||||
printf("\t%d, %d, %d, %d,\t/* async, debug, & reent flags */\n",
|
||||
async_flag, debug_flag, reent_flag, conn_flag);
|
||||
printf("\t");
|
||||
for (i = 0; i < NWRDS; i++)
|
||||
printf("0, ");
|
||||
printf("\t/* Event flags (bit encoded) */\n");
|
||||
|
||||
printf("\t0x%x,\t/* encoded async, debug, conn, newef & reent options */\n",
|
||||
encode_options() );
|
||||
|
||||
printf("\texit_handler,\t/* exit handler */\n");
|
||||
|
||||
@@ -302,6 +310,24 @@ gen_state_prog_table()
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
encode_options()
|
||||
{
|
||||
int options;
|
||||
|
||||
options = 0;
|
||||
if (async_opt)
|
||||
options |= OPT_ASYNC;
|
||||
if (conn_opt)
|
||||
options |= OPT_CONN;
|
||||
if (debug_opt)
|
||||
options |= OPT_DEBUG;
|
||||
if (reent_opt)
|
||||
options |= OPT_REENT;
|
||||
if (newef_opt)
|
||||
options |= OPT_NEWEF;
|
||||
return options;
|
||||
}
|
||||
/* Generate an array of state set control blocks (SSCB),
|
||||
one entry for each state set */
|
||||
gen_sscb_array()
|
||||
@@ -337,11 +363,6 @@ gen_sscb_array()
|
||||
|
||||
printf("\t0, FALSE,\t/* trans_number, action_complete */\n");
|
||||
|
||||
printf("\t/* outstanding events */\n\t");
|
||||
for (n = 0; n < NWRDS; n++)
|
||||
printf("0, ");
|
||||
printf("\n");
|
||||
|
||||
printf("\t0,\t/* pMask - ptr to current event mask */\n");
|
||||
|
||||
printf("\t0,\t/* number of delays in use */\n");
|
||||
|
||||
+18
-13
@@ -14,6 +14,7 @@
|
||||
19nov91,ajk Replaced lstLib calls with built-in links.
|
||||
20nov91,ajk Removed snc_init() - no longer did anything useful.
|
||||
20nov91,ajk Added option_stmt() routine.
|
||||
28apr92,ajk Implemented new event flag mode.
|
||||
***************************************************************************/
|
||||
|
||||
/*====================== Includes, globals, & defines ====================*/
|
||||
@@ -28,7 +29,7 @@
|
||||
#define FALSE 0
|
||||
#endif TRUE
|
||||
|
||||
int debug_print_flag = 0; /* Debug level (set by source file) */
|
||||
int debug_print_opt = 0; /* Debug level (set by source file) */
|
||||
|
||||
char *prog_name; /* ptr to program name (string) */
|
||||
|
||||
@@ -122,28 +123,32 @@ option_stmt(option, value)
|
||||
char *option; /* "a", "r", ... */
|
||||
int value; /* TRUE means +, FALSE means - */
|
||||
{
|
||||
extern int async_flag, conn_flag, debug_flag,
|
||||
line_flag, reent_flag, warn_flag;
|
||||
extern int async_opt, conn_opt, debug_opt,
|
||||
line_opt, reent_opt, warn_opt, newef_opt;
|
||||
|
||||
switch(*option)
|
||||
{
|
||||
case 'a':
|
||||
async_flag = value;
|
||||
async_opt = value;
|
||||
break;
|
||||
case 'c':
|
||||
conn_flag = value;
|
||||
conn_opt = value;
|
||||
break;
|
||||
case 'd':
|
||||
debug_flag = value;
|
||||
debug_opt = value;
|
||||
break;
|
||||
case 'l':
|
||||
line_flag = value;
|
||||
line_opt = value;
|
||||
break;
|
||||
case 'r':
|
||||
reent_flag = value;
|
||||
reent_opt = value;
|
||||
break;
|
||||
case 'w':
|
||||
warn_flag = value;
|
||||
warn_opt = value;
|
||||
|
||||
case 'e':
|
||||
newef_opt = value;
|
||||
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@@ -347,11 +352,11 @@ char *name; /* variable name */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set debug print flag */
|
||||
set_debug_print(flag)
|
||||
char *flag;
|
||||
/* Set debug print opt */
|
||||
set_debug_print(opt)
|
||||
char *opt;
|
||||
{
|
||||
debug_print_flag = atoi(flag);
|
||||
debug_print_opt = atoi(opt);
|
||||
}
|
||||
|
||||
/* Parsing "program" statement */
|
||||
|
||||
+15
-15
@@ -80,7 +80,7 @@ phase2()
|
||||
gen_preamble()
|
||||
{
|
||||
extern char *prog_name;
|
||||
extern int async_flag, conn_flag, debug_flag, reent_flag;
|
||||
extern int async_opt, conn_opt, debug_opt, reent_opt;
|
||||
|
||||
/* Program name (comment) */
|
||||
printf("/* Program \"%s\" */\n", prog_name);
|
||||
@@ -92,11 +92,11 @@ gen_preamble()
|
||||
printf("\n#define NUM_SS %d\n", num_ss);
|
||||
printf("#define NUM_CHANNELS %d\n", num_channels);
|
||||
|
||||
/* #define's for compiler flags */
|
||||
gen_flag_defn(async_flag, "ASYNC_FLAG");
|
||||
gen_flag_defn(conn_flag, "CONN_FLAG" );
|
||||
gen_flag_defn(debug_flag, "DEBUG_FLAG");
|
||||
gen_flag_defn(reent_flag, "REENT_FLAG");
|
||||
/* #define's for compiler options */
|
||||
gen_opt_defn(async_opt, "ASYNC_OPT");
|
||||
gen_opt_defn(conn_opt, "CONN_OPT" );
|
||||
gen_opt_defn(debug_opt, "DEBUG_OPT");
|
||||
gen_opt_defn(reent_opt, "REENT_OPT");
|
||||
printf("\n");
|
||||
|
||||
/* Forward references of tables: */
|
||||
@@ -106,11 +106,11 @@ gen_preamble()
|
||||
return;
|
||||
}
|
||||
|
||||
gen_flag_defn(flag, defn_name)
|
||||
int flag;
|
||||
gen_opt_defn(opt, defn_name)
|
||||
int opt;
|
||||
char *defn_name;
|
||||
{
|
||||
if (flag)
|
||||
if (opt)
|
||||
printf("#define %s TRUE\n", defn_name);
|
||||
else
|
||||
printf("#define %s FALSE\n", defn_name);
|
||||
@@ -148,12 +148,12 @@ Expr *ep;
|
||||
{
|
||||
Var *vp;
|
||||
extern char *stype[];
|
||||
extern int warn_flag;
|
||||
extern int warn_opt;
|
||||
|
||||
vp = (Var *)findVar(ep->value);
|
||||
if (vp == 0)
|
||||
{ /* variable not declared; add it to the variable list */
|
||||
if (warn_flag)
|
||||
if (warn_opt)
|
||||
fprintf(stderr,
|
||||
"Warning: variable \"%s\" is used but not declared.\n",
|
||||
ep->value);
|
||||
@@ -218,12 +218,12 @@ gen_var_decl()
|
||||
Var *vp;
|
||||
char *vstr;
|
||||
int nv;
|
||||
extern int reent_flag;
|
||||
extern int reent_opt;
|
||||
|
||||
printf("\n/* Variable declarations */\n");
|
||||
|
||||
/* Convert internal type to `C' type */
|
||||
if (reent_flag)
|
||||
if (reent_opt)
|
||||
printf("struct UserVar {\n");
|
||||
for (nv=0, vp = var_list; vp != NULL; nv++, vp = vp->next)
|
||||
{
|
||||
@@ -259,7 +259,7 @@ gen_var_decl()
|
||||
|
||||
if (vstr != NULL)
|
||||
{
|
||||
if (reent_flag)
|
||||
if (reent_opt)
|
||||
printf("\t");
|
||||
else
|
||||
printf("static ");
|
||||
@@ -271,7 +271,7 @@ gen_var_decl()
|
||||
printf(";\n");
|
||||
}
|
||||
}
|
||||
if (reent_flag)
|
||||
if (reent_opt)
|
||||
printf("};\n");
|
||||
return;
|
||||
}
|
||||
|
||||
+52
-24
@@ -27,9 +27,12 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 07-03-91 ajk .
|
||||
* .02 12-11-91 ajk Cosmetic changes (comments & names)
|
||||
* .03 02-13-92 ajk All seqLog() calls compile only if DEBUG is defined.
|
||||
* 03jul91,ajk .
|
||||
* 11dec91,ajk Cosmetic changes (comments & names)
|
||||
* 13feb92,ajk All seqLog() calls compile only if DEBUG is defined.
|
||||
* 28apr92,ajk Implemented new event flag mode.
|
||||
* 21may92,ajk Will periodically announce number of connected channels
|
||||
* if waiting form some to connect.
|
||||
*/
|
||||
|
||||
#include "seq.h"
|
||||
@@ -105,10 +108,20 @@ SPROG *pSP;
|
||||
}
|
||||
ca_flush_io();
|
||||
|
||||
if (pSP->conn_flag)
|
||||
{ /* Wait for all connections to complete */
|
||||
while (pSP->conn_count < pSP->nchan)
|
||||
taskDelay(30);
|
||||
if (pSP->options & OPT_CONN)
|
||||
{ /* Wait for all connections to complete ("+c" option) */
|
||||
for (i = 1; pSP->conn_count < pSP->nchan; i++)
|
||||
{
|
||||
if (i <= 2)
|
||||
taskDelay(6); /* 1-st 2 times we delay 0.1 sec */
|
||||
else
|
||||
taskDelay(30); /* thereafter we delay 0.5 sec */
|
||||
/* Log a message after about 5 sec
|
||||
* or about every 50 sec thereafter */
|
||||
if (i == 12 || (i % 100) == 0)
|
||||
logMsg("%d of %d channels connected\n",
|
||||
pSP->conn_count, pSP->nchan);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -197,8 +210,8 @@ struct connection_handler_args args;
|
||||
}
|
||||
|
||||
/*
|
||||
* seq_efSet() - Set an event flag. The result is to wake up each state
|
||||
* set that is waiting for event processing.
|
||||
* seq_efSet() - Set an event flag, then wake up each state
|
||||
* set that might be waiting on that event flag.
|
||||
*/
|
||||
VOID seq_efSet(pSP, dummy, ev_flag)
|
||||
SPROG *pSP;
|
||||
@@ -208,34 +221,49 @@ int ev_flag; /* event flag */
|
||||
SSCB *pSS;
|
||||
int nss;
|
||||
|
||||
pSS = pSP->sscb;
|
||||
/* For all state sets: */
|
||||
for (nss = 0; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
/* Apply resource lock */
|
||||
semTake(pSP->caSemId, WAIT_FOREVER);
|
||||
/* Set this bit (apply resource lock) */
|
||||
semTake(pSP->caSemId, WAIT_FOREVER);
|
||||
bitSet(pSP->events, ev_flag);
|
||||
|
||||
/* Check flag against mask for all state sets: */
|
||||
for (nss = 0, pSS = pSP->sscb; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
/* Test for possible event trig based on bit mask for this state */
|
||||
if ( (ev_flag == 0) || bitTest(pSS->pMask, ev_flag) )
|
||||
{
|
||||
bitSet(pSS->events, ev_flag);
|
||||
semGive(pSS->syncSemId); /* wake up the ss task */
|
||||
}
|
||||
|
||||
/* Unlock resource */
|
||||
semGive(pSP->caSemId);
|
||||
}
|
||||
|
||||
/* Unlock resource */
|
||||
semGive(pSP->caSemId);
|
||||
}
|
||||
|
||||
/*
|
||||
* seq_efTest() - Test event flag against outstanding events.
|
||||
*/
|
||||
seq_efTest(pSP, pSS, ev_flag)
|
||||
int seq_efTest(pSP, pSS, ev_flag)
|
||||
SPROG *pSP;
|
||||
SSCB *pSS;
|
||||
int ev_flag; /* event flag */
|
||||
{
|
||||
return bitTest(pSS->events, ev_flag);
|
||||
return bitTest(pSP->events, ev_flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* seq_efClear() - Test event flag against outstanding events, then clear it.
|
||||
*/
|
||||
int seq_efClear(pSP, pSS, ev_flag)
|
||||
SPROG *pSP;
|
||||
SSCB *pSS;
|
||||
int ev_flag; /* event flag */
|
||||
{
|
||||
int isSet;
|
||||
|
||||
isSet = bitTest(pSP->events, ev_flag);
|
||||
bitClear(pSP->events, ev_flag);
|
||||
return isSet;
|
||||
}
|
||||
/*
|
||||
* seq_pvGet() - Get DB value (uses channel access).
|
||||
@@ -256,7 +284,7 @@ CHAN *pDB; /* ptr to channel struct */
|
||||
pDB->get_complete = FALSE;
|
||||
|
||||
/* If synchronous pvGet then clear the pvGet pend semaphore */
|
||||
if (!pSP->async_flag)
|
||||
if ( !(pSP->options & OPT_ASYNC) )
|
||||
{
|
||||
pDB->getSemId = pSS->getSemId;
|
||||
semTake(pSS->getSemId, NO_WAIT);
|
||||
@@ -270,7 +298,7 @@ CHAN *pDB; /* ptr to channel struct */
|
||||
seq_callback_handler, /* callback handler */
|
||||
pDB); /* user arg */
|
||||
|
||||
if (pSP->async_flag || (status != ECA_NORMAL) )
|
||||
if ( (pSP->options & OPT_ASYNC) || (status != ECA_NORMAL) )
|
||||
return status;
|
||||
|
||||
/* Synchronous pvGet() */
|
||||
@@ -320,13 +348,13 @@ struct event_handler_args args;
|
||||
seq_efSet(pSP, 0, pDB->index + 1);
|
||||
|
||||
/* If syncronous pvGet then notify pending state set */
|
||||
if (!pSP->async_flag)
|
||||
if ( !(pSP->options & OPT_ASYNC) )
|
||||
semGive(pDB->getSemId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Flush requests */
|
||||
/* Flush outstanding CA requests */
|
||||
VOID seq_pvFlush()
|
||||
{
|
||||
ca_flush_io();
|
||||
|
||||
+59
-60
@@ -25,6 +25,10 @@
|
||||
11dec91,ajk Cleaned up comments.
|
||||
05feb92,ajk Decreased minimum allowable stack size to SPAWN_STACK_SIZE/2.
|
||||
24feb92,ajk Print error code for log file failure.
|
||||
28apr92,ajk Implemented new event flag mode.
|
||||
29apr92,ajk Now alocates private program structures, even when reentry option
|
||||
is not specified. This avoids problems with seqAddTask().
|
||||
29apr92,ajk Implemented mutual exclusion lock in seq_log().
|
||||
***************************************************************************/
|
||||
/*#define DEBUG 1*/
|
||||
|
||||
@@ -76,10 +80,12 @@ int stack_size; /* optional stack size (bytes) */
|
||||
SPROG *pSP, *alloc_task_area();
|
||||
char *seqMacValGet(), *pname, *pvalue, *ptask_name;
|
||||
|
||||
/* If no parameters specified, print version info. */
|
||||
/* Print version & date of sequencer */
|
||||
printf("%s\n", seqVersion);
|
||||
|
||||
/* Exit if no parameters specified */
|
||||
if (pSP_orig == 0)
|
||||
{
|
||||
printf("%s\n", seqVersion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -107,8 +113,7 @@ int stack_size; /* optional stack size (bytes) */
|
||||
pSP = alloc_task_area(pSP_orig);
|
||||
|
||||
/* Make a private copy of original structures (but change pointers!) */
|
||||
if (pSP_orig->reent_flag)
|
||||
copy_sprog(pSP_orig, pSP);
|
||||
copy_sprog(pSP_orig, pSP);
|
||||
|
||||
/* Initialize state program block */
|
||||
init_sprog(pSP);
|
||||
@@ -156,13 +161,13 @@ int stack_size; /* optional stack size (bytes) */
|
||||
pSP->name, ptask_name);
|
||||
seq_log(pSP, " Task id = %d = 0x%x\n", tid, tid);
|
||||
|
||||
/* Return task id to calling program */
|
||||
return tid;
|
||||
}
|
||||
|
||||
/*
|
||||
* ALLOC_TASK_AREA
|
||||
* Allocate a single block for all dynamic structures. The size allocated
|
||||
* will depend on whether or not the reentrant flag is set.
|
||||
* Allocate a single block for all dynamic structures
|
||||
* The pointer to the allocated area is saved for task delete hook routine.
|
||||
*/
|
||||
LOCAL SPROG *alloc_task_area(pSP_orig)
|
||||
@@ -187,17 +192,10 @@ SPROG *pSP_orig; /* original state program structure */
|
||||
scr_size = SCRATCH_SIZE;
|
||||
|
||||
/* Total # bytes to allocate */
|
||||
if (pSP_orig->reent_flag)
|
||||
{
|
||||
size = prog_size + ss_size + state_size +
|
||||
chan_size + user_size + mac_size + scr_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = mac_size + scr_size;
|
||||
}
|
||||
size = prog_size + ss_size + state_size +
|
||||
chan_size + user_size + mac_size + scr_size;
|
||||
|
||||
/* Alloc the task area */
|
||||
/* Alloc the dynamic task area */
|
||||
dyn_ptr = dyn_ptr_start = (char *)calloc(size, 1);
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -212,35 +210,34 @@ SPROG *pSP_orig; /* original state program structure */
|
||||
#endif DEBUG
|
||||
|
||||
/* Set ptrs in the PROG structure */
|
||||
if (pSP_orig->reent_flag)
|
||||
{ /* Reentry flag set: create a new structures */
|
||||
pSP_new = (SPROG *)dyn_ptr;
|
||||
pSP_new = (SPROG *)dyn_ptr;
|
||||
|
||||
/* Copy the SPROG struct contents */
|
||||
*pSP_new = *pSP_orig;
|
||||
/* Copy the SPROG struct contents */
|
||||
*pSP_new = *pSP_orig;
|
||||
|
||||
/* Allocate space for the other structures */
|
||||
dyn_ptr += prog_size;
|
||||
pSP_new->sscb = (SSCB *)dyn_ptr;
|
||||
dyn_ptr += ss_size;
|
||||
pSP_new->states = (STATE *)dyn_ptr;
|
||||
dyn_ptr += state_size;
|
||||
pSP_new->channels = (CHAN *)dyn_ptr;
|
||||
dyn_ptr += chan_size;
|
||||
/* Allocate space for copies of the original structures */
|
||||
dyn_ptr += prog_size;
|
||||
pSP_new->sscb = (SSCB *)dyn_ptr;
|
||||
dyn_ptr += ss_size;
|
||||
pSP_new->states = (STATE *)dyn_ptr;
|
||||
dyn_ptr += state_size;
|
||||
pSP_new->channels = (CHAN *)dyn_ptr;
|
||||
dyn_ptr += chan_size;
|
||||
if (user_size != 0)
|
||||
{
|
||||
pSP_new->user_area = (char *)dyn_ptr;
|
||||
dyn_ptr += user_size;
|
||||
}
|
||||
else
|
||||
{ /* Reentry flag not set: keep original structures */
|
||||
pSP_new = pSP_orig;
|
||||
}
|
||||
/* Create dynamic structures for macros and scratch area */
|
||||
pSP_new->user_area = NULL;
|
||||
|
||||
/* Create additional dynamic structures for macros and scratch area */
|
||||
pSP_new->mac_ptr = (MACRO *)dyn_ptr;
|
||||
dyn_ptr += mac_size;
|
||||
pSP_new->scr_ptr = (char *)dyn_ptr;
|
||||
pSP_new->scr_nleft = scr_size;
|
||||
|
||||
/* Save ptr to allocated area so we can free it at task delete */
|
||||
/* Save ptr to start of allocated area so we can free it at task delete */
|
||||
pSP_new->dyn_ptr = dyn_ptr_start;
|
||||
|
||||
return pSP_new;
|
||||
@@ -267,8 +264,7 @@ SPROG *pSP; /* new ptr */
|
||||
pSS = pSP->sscb;
|
||||
|
||||
/* Copy structures for each state set */
|
||||
pST = pSP->states;
|
||||
for (nss = 0; nss < pSP->nss; nss++)
|
||||
for (nss = 0, pST = pSP->states; nss < pSP->nss; nss++)
|
||||
{
|
||||
*pSS = *pSS_orig; /* copy SSCB */
|
||||
pSS->states = pST; /* new ptr to 1-st STATE */
|
||||
@@ -294,8 +290,11 @@ SPROG *pSP; /* new ptr */
|
||||
/* Reset ptr to SPROG structure */
|
||||
pDB->sprog = pSP;
|
||||
|
||||
/* Convert offset to address of the user variable */
|
||||
pDB->var += (int)var_ptr;
|
||||
/* +r: Convert offset to address of the user variable.
|
||||
* -r: var_ptr is an absolute address.
|
||||
*/
|
||||
if (pSP->options & OPT_REENT)
|
||||
pDB->var += (int)var_ptr;
|
||||
|
||||
pDB++;
|
||||
pDB_orig++;
|
||||
@@ -334,8 +333,7 @@ SPROG *pSP;
|
||||
SSCB *pSS;
|
||||
int nss, i;
|
||||
|
||||
pSS = pSP->sscb;
|
||||
for (nss = 0; nss < pSP->nss; nss++, pSS++)
|
||||
for (nss = 0, pSS = pSP->sscb; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
pSS->task_id = 0;
|
||||
/* Create a binary semaphore for synchronizing events in a SS */
|
||||
@@ -347,7 +345,7 @@ SPROG *pSP;
|
||||
}
|
||||
|
||||
/* Create a binary semaphore for pvGet() synconizing */
|
||||
if (!pSP->async_flag)
|
||||
if (!pSP->options & OPT_ASYNC)
|
||||
{
|
||||
pSS->getSemId =
|
||||
semBCreate(SEM_Q_FIFO, SEM_FULL);
|
||||
@@ -362,8 +360,6 @@ SPROG *pSP;
|
||||
pSS->current_state = 0; /* initial state */
|
||||
pSS->next_state = 0;
|
||||
pSS->action_complete = TRUE;
|
||||
for (i = 0; i < NWRDS; i++)
|
||||
pSS->events[i] = 0; /* clear events */
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -392,7 +388,8 @@ int nChar;
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Initialize logging
|
||||
* seq_logInit() - Initialize logging.
|
||||
* If "logfile" is not specified, then we log to standard output.
|
||||
*/
|
||||
LOCAL VOID seq_logInit(pSP)
|
||||
SPROG *pSP;
|
||||
@@ -422,7 +419,7 @@ SPROG *pSP;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* seqLog
|
||||
* seq_log
|
||||
* Log a message to the console or a file with time of day and task id.
|
||||
* The format looks like "mytask 12/13/91 10:07:43: <user's message>".
|
||||
*/
|
||||
@@ -461,6 +458,7 @@ int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; /* arguments */
|
||||
pBfr += count - 1;
|
||||
|
||||
/* Write the msg */
|
||||
semTake(pSP->logSemId, WAIT_FOREVER); /* lock it */
|
||||
fd = pSP->logFd;
|
||||
count = pBfr - logBfr + 1;
|
||||
status = write(fd, logBfr, count);
|
||||
@@ -476,7 +474,7 @@ int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; /* arguments */
|
||||
{
|
||||
ioctl(fd, FIOSYNC);
|
||||
}
|
||||
|
||||
semGive(pSP->logSemId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -498,19 +496,20 @@ int arg1,arg2, arg3, arg4, arg5, arg6, arg7, arg8; /* arguments */
|
||||
return OK;
|
||||
}
|
||||
/*
|
||||
* seq_flagGet: return the value of an option flag.
|
||||
* seq_optGet: return the value of an option.
|
||||
* FALSE means "-" and TRUE means "+".
|
||||
*/
|
||||
BOOL seq_flagGet(pSP, flag)
|
||||
BOOL seq_optGet(pSP, opt)
|
||||
SPROG *pSP;
|
||||
char *flag; /* one of the snc flags as a strign (e.g. "a") */
|
||||
char *opt; /* one of the snc options as a strign (e.g. "a") */
|
||||
{
|
||||
switch (flag[0])
|
||||
switch (opt[0])
|
||||
{
|
||||
case 'a': return pSP->async_flag;
|
||||
case 'c': return pSP->conn_flag;
|
||||
case 'd': return pSP->debug_flag;
|
||||
case 'r': return pSP->reent_flag;
|
||||
case 'a': return ( (pSP->options & OPT_ASYNC) != 0);
|
||||
case 'c': return ( (pSP->options & OPT_CONN) != 0);
|
||||
case 'd': return ( (pSP->options & OPT_DEBUG) != 0);
|
||||
case 'r': return ( (pSP->options & OPT_REENT) != 0);
|
||||
case 'e': return ( (pSP->options & OPT_NEWEF) != 0);
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -547,17 +546,17 @@ SPROG *pSP;
|
||||
printf(" task pri=%d\n", pSP->task_priority);
|
||||
printf(" number of state sets=%d\n", pSP->nss);
|
||||
printf(" number of channels=%d\n", pSP->nchan);
|
||||
printf(" async flag=%d, debug flag=%d, reent flag=%d\n",
|
||||
pSP->async_flag, pSP->debug_flag, pSP->reent_flag);
|
||||
printf(" options:
|
||||
printf(" async=%d, debug=%d, conn=%d, reent=%d, newef=%d\n",
|
||||
seq_optGet(pSP, 'a'), seq_optGet(pSP, 'd'), seq_optGet(pSP, 'c'),
|
||||
seq_optGet(pSP, 'r'), seq_optGet(pSP, 'e'));
|
||||
|
||||
pSS = pSP->sscb;
|
||||
for (nss = 0; nss < pSP->nss; nss++, pSS++)
|
||||
for (nss = 0, pSS = pSP->sscb; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
printf(" State Set: \"%s\"\n", pSS->name);
|
||||
printf(" Num states=\"%d\"\n", pSS->num_states);
|
||||
printf(" State names:\n");
|
||||
pST = pSS->states;
|
||||
for (nstates = 0; nstates < pSS->num_states; nstates++)
|
||||
for (nstates = 0, pST = pSS->states; nstates < pSS->num_states; nstates++)
|
||||
{
|
||||
printf(" \"%s\"\n", pST->name);
|
||||
pST++;
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
ENVIRONMENT: VxWorks
|
||||
|
||||
HISTORY:
|
||||
09dec91,ajk original ***************************************************************************/
|
||||
|
||||
09dec91,ajk original
|
||||
29apr92,ajk Added mutual exclusion locks
|
||||
***************************************************************************/
|
||||
#define DEBUG
|
||||
#include "seq.h"
|
||||
|
||||
LOCAL SEM_ID seqProgListSemId;
|
||||
@@ -43,19 +45,28 @@ int task_id;
|
||||
if (!seqProgListInited || task_id == 0)
|
||||
return NULL;
|
||||
|
||||
semTake(seqProgListSemId, WAIT_FOREVER);
|
||||
|
||||
for (pNode = seqListFirst(&seqProgList); pNode != NULL;
|
||||
pNode = seqListNext(pNode) )
|
||||
{
|
||||
pSP = pNode->pSP;
|
||||
if (pSP->task_id == task_id)
|
||||
{
|
||||
semGive(seqProgListSemId);
|
||||
return pSP;
|
||||
}
|
||||
pSS = pSP->sscb;
|
||||
for (n = 0; n < pSP->nss; n++, pSS++)
|
||||
{
|
||||
if (pSS->task_id == task_id)
|
||||
{
|
||||
semGive(seqProgListSemId);
|
||||
return pSP;
|
||||
}
|
||||
}
|
||||
}
|
||||
semGive(seqProgListSemId);
|
||||
|
||||
return NULL; /* not in list */
|
||||
}
|
||||
@@ -75,6 +86,7 @@ VOID *param; /* any parameter */
|
||||
if (!seqProgListInited)
|
||||
return ERROR;
|
||||
|
||||
semTake(seqProgListSemId, WAIT_FOREVER);
|
||||
for (pNode = seqListFirst(&seqProgList); pNode != NULL;
|
||||
pNode = seqListNext(pNode) )
|
||||
{
|
||||
@@ -82,6 +94,7 @@ VOID *param; /* any parameter */
|
||||
pFunc(pSP, param);
|
||||
}
|
||||
|
||||
semGive(seqProgListSemId);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -97,21 +110,35 @@ SPROG *pSP;
|
||||
if (!seqProgListInited)
|
||||
seqProgListInit(); /* Initialize list */
|
||||
|
||||
semTake(seqProgListSemId, WAIT_FOREVER);
|
||||
for (pNode = seqListFirst(&seqProgList); pNode != NULL;
|
||||
pNode = seqListNext(pNode) )
|
||||
{
|
||||
|
||||
if (pSP == pNode->pSP)
|
||||
{
|
||||
semGive(seqProgListSemId);
|
||||
#ifdef DEBUG
|
||||
printf("Task %d already in list\n", pSP->task_id);
|
||||
#endif
|
||||
return ERROR; /* already in list */
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert at head of list */
|
||||
pNode = (PROG_NODE *)malloc(sizeof(PROG_NODE) );
|
||||
if (pNode == NULL)
|
||||
{
|
||||
semGive(seqProgListSemId);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
pNode->pSP = pSP;
|
||||
lstAdd(&seqProgList, pNode);
|
||||
semGive(seqProgListSemId);
|
||||
#ifdef DEBUG
|
||||
printf("Added task %d to list.\n", pSP->task_id);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -128,16 +155,23 @@ SPROG *pSP;
|
||||
if (!seqProgListInited)
|
||||
return ERROR;
|
||||
|
||||
semTake(seqProgListSemId, WAIT_FOREVER);
|
||||
for (pNode = seqListFirst(&seqProgList); pNode != NULL;
|
||||
pNode = seqListNext(pNode) )
|
||||
{
|
||||
if (pNode->pSP == pSP)
|
||||
{
|
||||
lstDelete(&seqProgList, pNode);
|
||||
semGive(seqProgListSemId);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Deleted task %d from list.\n", pSP->task_id);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
semGive(seqProgListSemId);
|
||||
return ERROR; /* not in list */
|
||||
}
|
||||
|
||||
@@ -151,6 +185,7 @@ LOCAL seqProgListInit()
|
||||
|
||||
/* Create a semaphore for mutual exclusion */
|
||||
seqProgListSemId = semBCreate(0);
|
||||
semGive(seqProgListSemId);
|
||||
|
||||
seqProgListInited = TRUE;
|
||||
|
||||
|
||||
+22
-8
@@ -18,6 +18,8 @@
|
||||
19dec91,ajk Allow task name as well as task id.
|
||||
25feb92,ajk V5.0 accepts 0 as a valid task id: fixed it.
|
||||
26feb92,ajk Fixed formatting of task/program listing.
|
||||
29apr92,ajk Modified to interpret encoded options.
|
||||
21may92,ajk Modified format for listing programs & tasks.
|
||||
***************************************************************************/
|
||||
|
||||
/* #define DEBUG 1 */
|
||||
@@ -79,19 +81,19 @@ int tid;
|
||||
printf(" number of state sets=%d\n", pSP->nss);
|
||||
printf(" number of channels=%d\n", pSP->nchan);
|
||||
printf(" number of channels connected=%d\n", pSP->conn_count);
|
||||
printf(" async flag=%d, debug flag=%d, reent flag=%d, conn flag=%d\n",
|
||||
pSP->async_flag, pSP->debug_flag, pSP->reent_flag,
|
||||
pSP->conn_flag);
|
||||
printf(" options: async=%d, debug=%d, reent=%d, conn=%d, newef=%d\n",
|
||||
((pSP->options & OPT_ASYNC) != 0), ((pSP->options & OPT_DEBUG) != 0),
|
||||
((pSP->options & OPT_REENT) != 0), ((pSP->options & OPT_CONN) != 0),
|
||||
((pSP->options & OPT_NEWEF) != 0) );
|
||||
printf(" log file fd=%d\n", pSP->logFd);
|
||||
status = ioctl(pSP->logFd, FIOGETNAME, file_name);
|
||||
if (status != ERROR)
|
||||
printf(" log file name=\"%s\"\n", file_name);
|
||||
|
||||
printf("\n");
|
||||
pSS = pSP->sscb;
|
||||
|
||||
/* Print state set info */
|
||||
for (nss = 0; nss < pSP->nss; nss++, pSS++)
|
||||
for (nss = 0, pSS = pSP->sscb; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
wait_rtn();
|
||||
|
||||
@@ -333,12 +335,24 @@ LOCAL seqShowSP(pSP)
|
||||
SPROG *pSP;
|
||||
{
|
||||
SSCB *pSS;
|
||||
int nss;
|
||||
char *progName, *ptaskName;;
|
||||
|
||||
pSS = pSP->sscb;
|
||||
if (seqProgCount++ == 0)
|
||||
printf("TID Program Name Task Name\n");
|
||||
printf("Program Name Task ID Task Name SS Name\n\n");
|
||||
|
||||
printf("%-10d %-18s %-18s\n", pSP->task_id,pSP->name, taskName(pSS->task_id) );
|
||||
progName = pSP->name;
|
||||
for (nss = 0, pSS = pSP->sscb; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
if (pSS->task_id == 0)
|
||||
ptaskName = "(no task)";
|
||||
else
|
||||
ptaskName = taskName(pSS->task_id);
|
||||
printf("%-16s %-10d %-16s %-16s\n",
|
||||
progName, pSS->task_id, ptaskName, pSS->name );
|
||||
progName = "";
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Print a brief summary of all state programs */
|
||||
|
||||
+72
-51
@@ -1,7 +1,8 @@
|
||||
/**************************************************************************
|
||||
GTA PROJECT AT division
|
||||
Copyright, 1990, The Regents of the University of California.
|
||||
Los Alamos National Laboratory
|
||||
Copyright, 1990, 1991, 1992
|
||||
The Regents of the University of California
|
||||
Los Alamos National Laboratory
|
||||
|
||||
$Id$
|
||||
DESCRIPTION: Seq_tasks.c: Task creation and control for sequencer
|
||||
@@ -12,7 +13,11 @@
|
||||
04dec91,ajk Implemented linked list of state programs, eliminating task
|
||||
variables.
|
||||
11dec91,ajk Made cosmetic changes and cleaned up comments.
|
||||
19dec91,ajk Changed algoritm in get_timeout().
|
||||
19dec91,ajk Changed algoritm in seq_getTimeout().
|
||||
29apr92,ajk Implemented new event flag mode.
|
||||
30apr92,ajk Periodically call ca_pend_event() to detect connection failures.
|
||||
21may92,ajk In sprog_delete() wait for loggin semaphore before suspending tasks.
|
||||
Some minor changes in the way semaphores are deleted.
|
||||
***************************************************************************/
|
||||
|
||||
#include "seq.h"
|
||||
@@ -20,15 +25,15 @@
|
||||
/* Function declarations */
|
||||
#ifdef ANSI
|
||||
LOCAL VOID ss_task_init(SPROG *, SSCB *);
|
||||
LOCAL long get_timeout(SSCB *);
|
||||
long seq_getTimeout(SSCB *);
|
||||
#else
|
||||
LOCAL VOID ss_task_init();
|
||||
LOCAL long get_timeout();
|
||||
long seq_getTimeout();
|
||||
#endif ANSI
|
||||
|
||||
#define TASK_NAME_SIZE 10
|
||||
|
||||
#define MAX_TIMEOUT (1<<30) /* like 2 years */
|
||||
#define MAX_DELAY (60*10) /* max delay time pending for events */
|
||||
|
||||
/*
|
||||
* sequencer() - Sequencer main task entry point.
|
||||
@@ -40,11 +45,17 @@ char *ptask_name; /* Parent task name */
|
||||
{
|
||||
SSCB *pSS;
|
||||
STATE *pST;
|
||||
int nss, task_id;
|
||||
int nss, task_id, i;
|
||||
char task_name[TASK_NAME_SIZE+10];
|
||||
extern VOID ss_entry();
|
||||
|
||||
pSP->task_id = taskIdSelf(); /* my task id */
|
||||
pSS = pSP->sscb;
|
||||
pSS->task_id = pSP->task_id;
|
||||
|
||||
/* Clear all event flags */
|
||||
for (i = 0; i < NWRDS; i++)
|
||||
pSP->events[i] = 0;
|
||||
|
||||
/* Add the program to the state program list */
|
||||
seqAddProg(pSP);
|
||||
@@ -61,8 +72,7 @@ char *ptask_name; /* Parent task name */
|
||||
ptask_name[TASK_NAME_SIZE] = 0;
|
||||
|
||||
/* Create each additional state set task */
|
||||
pSS = pSP->sscb + 1;
|
||||
for (nss = 1; nss < pSP->nss; nss++, pSS++)
|
||||
for (nss = 1, pSS = pSP->sscb + 1; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
/* Form task name from program name + state set number */
|
||||
sprintf(task_name, "%s_%d", ptask_name, nss);
|
||||
@@ -93,7 +103,6 @@ SSCB *pSS;
|
||||
BOOL ev_trig;
|
||||
STATE *pST, *pStNext;
|
||||
long delay;
|
||||
int i;
|
||||
char *pVar;
|
||||
|
||||
pSS->task_id = taskIdSelf();
|
||||
@@ -117,12 +126,6 @@ SSCB *pSS;
|
||||
*/
|
||||
while (1)
|
||||
{
|
||||
/* Clear event bits */
|
||||
semTake(pSP->caSemId, WAIT_FOREVER); /* Lock CA event update */
|
||||
for (i = 0; i < NWRDS; i++)
|
||||
pSS->events[i] = 0;
|
||||
semGive(pSP->caSemId); /* Unlock CA event update */
|
||||
|
||||
pSS->time = tickGet(); /* record time we entered this state */
|
||||
|
||||
/* Call delay function to set up delays */
|
||||
@@ -135,25 +138,34 @@ SSCB *pSS;
|
||||
semGive(pSS->syncSemId);
|
||||
|
||||
/*
|
||||
* Loop until an event is triggered, i.e. when()
|
||||
* returns TRUE.
|
||||
* Loop until an event is triggered, i.e. when() returns TRUE
|
||||
* or at least every MAX_DELAY ticks.
|
||||
*
|
||||
*/
|
||||
do {
|
||||
/* Allow CA to check for connect/disconnect on channels */
|
||||
if (pSP->task_id == pSS->task_id)
|
||||
ca_pend_event(0.001); /* returns immediately */
|
||||
|
||||
/* Wake up on CA event, event flag, or expired time delay */
|
||||
delay = get_timeout(pSS);
|
||||
delay = seq_getTimeout(pSS);
|
||||
if (delay > 0)
|
||||
semTake(pSS->syncSemId, delay);
|
||||
|
||||
/* Apply resource lock: any new events coming in will
|
||||
be deferred until next state is entered */
|
||||
/* Call the event function to check for an event trigger.
|
||||
* The statement inside the when() statement is executed.
|
||||
* Note, we lock out CA events while doing this.
|
||||
*/
|
||||
semTake(pSP->caSemId, WAIT_FOREVER);
|
||||
|
||||
/* Call the event function to check for an event trigger.
|
||||
* Everything inside the when() statement is executed.
|
||||
*/
|
||||
ev_trig = pST->event_func(pSP, pSS, pVar);
|
||||
ev_trig = pST->event_func(pSP, pSS, pVar); /* check events */
|
||||
|
||||
/* Unlock CA resource */
|
||||
if ( ev_trig && (pSP->options & OPT_NEWEF) == 0 )
|
||||
{ /* Clear all event flags (old mode only) */
|
||||
register int i;
|
||||
for (i = 0; i < NWRDS; i++)
|
||||
pSP->events[i] = pSP->events[i] & !pSS->pMask[i];
|
||||
}
|
||||
semGive(pSP->caSemId);
|
||||
|
||||
} while (!ev_trig);
|
||||
@@ -190,39 +202,41 @@ SSCB *pSS;
|
||||
|
||||
return;
|
||||
}
|
||||
/* Return time-out for delay() */
|
||||
LOCAL long get_timeout(pSS)
|
||||
/*
|
||||
* seq_getTimeout() - return time-out for pending on events.
|
||||
* Returns number of tics to next expected timeout of a delay() call.
|
||||
* Returns MAX_DELAY if no delays pending */
|
||||
long seq_getTimeout(pSS)
|
||||
SSCB *pSS;
|
||||
{
|
||||
int ndelay;
|
||||
long timeout, timeoutMin; /* expiration clock time */
|
||||
long delay; /* min. delay (tics) */
|
||||
long timeout; /* expiration clock time (tics) */
|
||||
long delay, delayMin; /* remaining & min. delay (tics) */
|
||||
|
||||
if (pSS->ndelay == 0)
|
||||
return MAX_TIMEOUT;
|
||||
return MAX_DELAY;
|
||||
|
||||
timeoutMin = MAX_TIMEOUT; /* start with largest timeout */
|
||||
delayMin = MAX_DELAY; /* start with largest possible delay */
|
||||
|
||||
/* Find the minimum abs. timeout (0 means already expired) */
|
||||
/* Find the minimum delay among all non-expired timeouts */
|
||||
for (ndelay = 0; ndelay < pSS->ndelay; ndelay++)
|
||||
{
|
||||
timeout = pSS->timeout[ndelay];
|
||||
if (timeout == 0)
|
||||
continue; /* already expired */
|
||||
if (pSS->time >= timeout)
|
||||
delay = timeout - tickGet(); /* convert timeout to remaining delay */
|
||||
if (delay <= 0)
|
||||
{ /* just expired */
|
||||
timeoutMin = pSS->time;
|
||||
delayMin = 0;
|
||||
pSS->timeout[ndelay] = 0; /* mark as expired */
|
||||
}
|
||||
else if (timeout < timeoutMin)
|
||||
else if (delay < delayMin)
|
||||
{
|
||||
timeoutMin = timeout;
|
||||
delayMin = delay; /* this is the min. delay so far */
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert minimum timeout to delay */
|
||||
delay = timeoutMin - tickGet();
|
||||
return delay;
|
||||
return delayMin;
|
||||
}
|
||||
/* Set-up for delay() on entering a state. This routine is called
|
||||
by the state program for each delay in the "when" statement */
|
||||
@@ -306,6 +320,9 @@ TCBX *pTcbX; /* ptr to TCB of task to be deleted */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait for log semaphore (in case a task is doing a write) */
|
||||
semTake(pSP->logSemId, 600);
|
||||
|
||||
/* Suspend all state set tasks except self */
|
||||
pSS = pSP->sscb;
|
||||
#ifdef DEBUG
|
||||
@@ -314,7 +331,7 @@ TCBX *pTcbX; /* ptr to TCB of task to be deleted */
|
||||
for (nss = 0; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
tid_ss = pSS->task_id;
|
||||
if ( (tid_ss > 0) && (tid != tid_ss) )
|
||||
if ( (tid_ss != 0) && (tid != tid_ss) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
logMsg(" suspend task: tid=%d\n", tid_ss);
|
||||
@@ -323,8 +340,11 @@ TCBX *pTcbX; /* ptr to TCB of task to be deleted */
|
||||
}
|
||||
}
|
||||
|
||||
/* Give back log semaphore */
|
||||
semGive(pSP->logSemId);
|
||||
|
||||
/* Call user exit routine (only if task has run) */
|
||||
if (pSP->sscb->task_id > 0)
|
||||
if (pSP->sscb->task_id != 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
logMsg(" Call exit function\n");
|
||||
@@ -350,23 +370,24 @@ TCBX *pTcbX; /* ptr to TCB of task to be deleted */
|
||||
for (nss = 0; nss < pSP->nss; nss++, pSS++)
|
||||
{
|
||||
tid_ss = pSS->task_id;
|
||||
if ( tid_ss > 0)
|
||||
if ( (tid != tid_ss) && (tid_ss != 0) )
|
||||
{
|
||||
if ( (tid != tid_ss) && (tid_ss > 0) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
logMsg(" delete ss task: tid=%d\n", tid_ss);
|
||||
logMsg(" delete ss task: tid=%d\n", tid_ss);
|
||||
#endif DEBUG
|
||||
taskDelete(tid_ss);
|
||||
}
|
||||
semDelete(pSS->syncSemId);
|
||||
if (!pSP->async_flag)
|
||||
semDelete(pSS->getSemId);
|
||||
taskDelete(tid_ss);
|
||||
}
|
||||
|
||||
if (pSS->syncSemId != 0)
|
||||
semDelete(pSS->syncSemId);
|
||||
|
||||
if (pSS->getSemId != 0)
|
||||
semDelete(pSS->getSemId);
|
||||
}
|
||||
|
||||
/* Delete program-wide semaphores */
|
||||
semDelete(pSP->caSemId);
|
||||
semDelete(pSP->logSemId);
|
||||
|
||||
/* Free the memory that was allocated for the task area */
|
||||
#ifdef DEBUG
|
||||
|
||||
+29
-22
@@ -11,6 +11,7 @@
|
||||
HISTORY:
|
||||
20nov91,ajk Removed call to init_snc().
|
||||
20nov91,ajk Removed some debug stuff.
|
||||
28apr92,ajk Implemented new event flag mode.
|
||||
***************************************************************************/
|
||||
extern char *sncVersion; /* snc version and date created */
|
||||
|
||||
@@ -27,13 +28,14 @@ char out_file[200]; /* output file name */
|
||||
char *src_file; /* ptr to (effective) source file name */
|
||||
int line_num; /* current src file line number */
|
||||
int c_line_num; /* line number for beginning of C code */
|
||||
/* Flags: */
|
||||
int async_flag = FALSE; /* do pvGet() asynchronously */
|
||||
int conn_flag = TRUE; /* wait for all connections to complete */
|
||||
int debug_flag = FALSE; /* run-time debug */
|
||||
int line_flag = TRUE; /* line numbering */
|
||||
int reent_flag = FALSE; /* reentrant at run-time */
|
||||
int warn_flag = TRUE; /* compiler warnings */
|
||||
/* Compile & run-time options: */
|
||||
int async_opt = FALSE; /* do pvGet() asynchronously */
|
||||
int conn_opt = TRUE; /* wait for all connections to complete */
|
||||
int debug_opt = FALSE; /* run-time debug */
|
||||
int newef_opt = TRUE; /* use new event flag mode */
|
||||
int line_opt = TRUE; /* line numbering */
|
||||
int reent_opt = FALSE; /* reentrant at run-time */
|
||||
int warn_opt = TRUE; /* compiler warnings */
|
||||
|
||||
/*+************************************************************************
|
||||
* NAME: main
|
||||
@@ -125,6 +127,7 @@ char *argv[];
|
||||
fprintf(stderr, " -l - supress line numbering\n");
|
||||
fprintf(stderr, " +r - make reentrant at run-time\n");
|
||||
fprintf(stderr, " -w - supress compiler warnings\n");
|
||||
fprintf(stderr, " -e - don't use new event flag mode\n");
|
||||
fprintf(stderr, "example:\n snc +a -c vacuum.st\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -133,51 +136,55 @@ char *argv[];
|
||||
{
|
||||
s = *argv;
|
||||
if (*s == '+' || *s == '-')
|
||||
get_flag(s);
|
||||
get_options(s);
|
||||
else
|
||||
get_in_file(s);
|
||||
}
|
||||
}
|
||||
|
||||
get_flag(s)
|
||||
get_options(s)
|
||||
char *s;
|
||||
{
|
||||
int flag_val;
|
||||
extern int debug_flag, line_flag, reent_flag, warn_flag;
|
||||
int opt_val;
|
||||
extern int debug_opt, line_opt, reent_opt, warn_opt, async_opt, newef_opt;
|
||||
|
||||
if (*s == '+')
|
||||
flag_val = TRUE;
|
||||
opt_val = TRUE;
|
||||
else
|
||||
flag_val = FALSE;
|
||||
opt_val = FALSE;
|
||||
|
||||
switch (s[1])
|
||||
{
|
||||
case 'a':
|
||||
async_flag = flag_val;
|
||||
async_opt = opt_val;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
conn_flag = flag_val;
|
||||
conn_opt = opt_val;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
debug_flag = flag_val;
|
||||
debug_opt = opt_val;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
line_flag = flag_val;
|
||||
line_opt = opt_val;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
reent_flag = flag_val;
|
||||
reent_opt = opt_val;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
warn_flag = flag_val;
|
||||
warn_opt = opt_val;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
newef_opt = opt_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown flag: \"%s\"\n", s);
|
||||
fprintf(stderr, "Unknown option: \"%s\"\n", s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -275,9 +282,9 @@ print_line_num(line_num, src_file)
|
||||
int line_num;
|
||||
char *src_file;
|
||||
{
|
||||
extern int line_flag;
|
||||
extern int line_opt;
|
||||
|
||||
if (line_flag)
|
||||
if (line_opt)
|
||||
printf("# line %d \"%s\"\n", line_num, src_file);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user