Ported ajk version from lanl

This commit is contained in:
Bob Zieman
1992-07-13 23:42:38 +00:00
parent ec4d509b0b
commit b50cc8499d
11 changed files with 351 additions and 216 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
1.7.10
1.8_Test
+13 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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++;
+37 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}