Update from PSI

r1039 | ffr | 2006-08-03 09:59:29 +1000 (Thu, 03 Aug 2006) | 2 lines
This commit is contained in:
Ferdi Franceschini
2006-08-03 09:59:29 +10:00
committed by Douglas Clowes
parent 4aa50787c2
commit 074f1cb3cd
63 changed files with 1431 additions and 286 deletions

258
devexec.c
View File

@@ -9,6 +9,9 @@
revised for use with tasker: Mark Koennecke, September 1997
Locking added: Mark Koennecke, August 2002
Refactored and instrumentation for instrument staticstics added.
Mark Koennecke, July 2006
Copyright:
Labor fuer Neutronenstreuung
@@ -39,10 +42,12 @@
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
-----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include "fortify.h"
#include "sics.h"
#include "nserver.h"
@@ -52,11 +57,52 @@
#include "devexec.h"
#include "status.h"
#include "lld.h"
#include "commandlog.h"
#include "ifile.h"
/*
#define DEBUG 1
*/
/*======================== Logging stuff ==================================*/
static FILE *devLog = NULL;
/*-------------------------------------------------------------------------*/
int openDevexecLog(){
char *fileName = NULL;
char fileBuffer[1024];
if(devLog == NULL){
fileName = IFindOption(pSICSOptions,"devexeclog");
if(fileName != NULL){
strcpy(fileBuffer,fileName);
} else {
fileBuffer[0] = '\0';
fileName = getenv("HOME");
if(fileName != NULL){
strcpy(fileBuffer,fileName);
}
strcat(fileBuffer,"/log/devexec.log");
}
devLog = fopen(fileBuffer,"a+");
}
if(devLog == NULL){
return 0;
} else {
return 1;
}
}
/*-------------------------------------------------------------------------*/
void DevexecLog(char *operation, char *device) {
struct timeval tv;
struct timezone tm;
if(devLog != NULL){
gettimeofday(&tv,&tm);
fprintf(devLog, "DEVEXEC:%s:%s:%ld:%ld\n",operation,device,
tv.tv_sec, tv.tv_usec);
fflush(devLog);
}
}
/*======================== internal data structures =======================*/
typedef struct _DevEntry {
void *pData;
pObjectDescriptor pDescriptor;
@@ -64,6 +110,13 @@
char *name;
commandContext comCon;
} DevEntry, *pDevEntry;
/*------------------------------------------------------------------------*/
typedef struct {
pExeList self;
pDevEntry pDev;
pICountable pCountInt;
pIDrivable pDrivInt;
}checkContext, *pCheckContext;
/*-------------------------------------------------------------------------*/
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
float fVal, char *name)
@@ -111,6 +164,7 @@
int iLock;
pICallBack pCall;
time_t lastRun;
int paused;
} ExeList;
static pExeList pExecutor = NULL;
@@ -167,6 +221,10 @@
free(self);
pServ->pExecutor = NULL;
if(devLog != NULL){
fclose(devLog);
devLog = NULL;
}
}
/*--------------------------------------------------------------------------*/
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
@@ -284,6 +342,7 @@
self->iEnd = 0;
pCon->conStatus = HWBusy;
}
DevexecLog("START",pNew->name);
return 1;
}
else
@@ -386,7 +445,7 @@
pCon,pCter->pDriv->fPreset);
}
/*--------------------------------------------------------------------------*/
int CheckExeList(pExeList self)
int CheckExeListOld(pExeList self)
{
int iRet;
pDevEntry pDev = NULL;
@@ -402,7 +461,7 @@
/* Sometimes this gets called, though nothing is running. There are
cases where this is feasible for maintainance, but in some cases it
is pure rubbish, because nothing runs. This will ne checkd here.
is pure rubbish, because nothing runs. This will be checked here.
*/
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY))
{
@@ -421,10 +480,7 @@
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
/*
SCSetContext(self->pOwner,pDev->cmdID,pDev->name);
*/
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
@@ -560,6 +616,196 @@
return 0;
}
}
/*-------------------------------------------------------------------------*/
static int checkInterrupt(pCheckContext pCheck, int targetStatus){
if(SCGetInterrupt(pCheck->self->pOwner) != eContinue) {
pCheck->self->iStatus = DEVINT;
SCPopContext(pCheck->self->pOwner);
SetStatus(eEager);
return -1;
} else {
return targetStatus;
}
}
/*--------------------------------------------------------------------------*/
static int initializeCheck(pCheckContext pCheck, pDevEntry pDev){
int eCode;
SCPushContext(pCheck->self->pOwner,
pDev->comCon.transID, pDev->comCon.deviceID);
pCheck->pDev = pDev;
pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCheck->pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCheck->pDrivInt != NULL){
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pCheck->self->pOwner);
} else if(pCheck->pCountInt != NULL) {
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pCheck->self->pOwner);
}
return eCode;
}
/*--------------------------------------------------------------------------*/
static int finishDevice(pCheckContext pCheck){
int status;
if(pCheck->pCountInt != NULL) {
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->self->pOwner);
} else if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount = 0;
}
ExeInterest(pCheck->self, pCheck->pDev, "finished");
DevexecLog("STOP",pCheck->pDev->name);
DeleteDevEntry(pCheck->pDev);
LLDnodeDelete(pCheck->self->iList);
status = LLDnodePtr2Prev(pCheck->self->iList);
SCWrite(pCheck->self->pOwner, "", eFinish);
pCheck->self->iStatus = DEVDONE;
return checkInterrupt(pCheck,status);
}
/*-------------------------------------------------------------------------*/
static int errorDevice(pCheckContext pCheck){
int status;
ExeInterest(pCheck->self, pCheck->pDev, "finished with problem");
DevexecLog("STOP",pCheck->pDev->name);
DeleteDevEntry(pCheck->pDev);
LLDnodeDelete(pCheck->self->iList);
status = LLDnodePtr2Prev(pCheck->self->iList);
SCWrite(pCheck->self->pOwner, "", eFinish);
pCheck->self->iStatus = DEVERROR;
if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount++;
}
return checkInterrupt(pCheck,status);
}
/*-------------------------------------------------------------------------*/
static int testFinish(pExeList self){
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
self->pOwner = NULL;
self->iRun = 0;
self->iEnd = 1;
self->iStop = 0;
self->lTask = -1;
return 1;
} else {
return 0;
}
}
/*--------------------------------------------------------------------------*/
int CheckExeList(pExeList self)
{
int iRet, status;
checkContext check;
pDevEntry pDev = NULL;
pICountable pCountInt = NULL;
pIDrivable pDrivInt = NULL;
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
/* Sometimes this gets called, though nothing is running. There are
cases where this is feasible for maintainance, but in some cases it
is pure rubbish, because nothing runs. This will be checked here.
*/
if(testFinish(self) == 1){
return 1;
}
/*
check the status of all registered devices. Remove when finished
*/
check.self = self;
status = LLDnodePtr2First(self->iList);
while(status != 0)
{
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
eCode = initializeCheck(&check,pDev);
if(eCode != HWNoBeam && eCode != HWPause && self->paused == 1){
DevexecLog("CONTINUE","ALL");
self->paused = 0;
}
switch(eCode)
{
case HWIdle:
case OKOK:
status = finishDevice(&check);
if(status < 0){
return status;
}
break;
case HWFault: /* real HW error: burning, no net etc.. */
status = errorDevice(&check);
if(status < 0){
return status;
}
break;
case HWNoBeam:
SetStatus(eOutOfBeam);
if(self->paused == 0){
self->paused = 1;
DevexecLog("NOBEAM","ALL");
}
status = checkInterrupt(&check,1);
if(status < 0){
return status;
}
break;
case HWPause:
SetStatus(ePaused);
if(self->paused == 0){
self->paused = 1;
DevexecLog("PAUSE","ALL");
}
status = checkInterrupt(&check,1);
if(status < 0){
/*
* continue in order to wait for devices to come to a stop
*/
ContinueExecution(self);
return status;
}
break;
case HWBusy:
if(check.pDrivInt != NULL)
{
isDriving = 1;
}
else if(check.pCountInt != NULL)
{
isCounting = 1;
}
self->iStatus = DEVBUSY;
break;
case HWPosFault: /* cannot get somewhere... */
status = errorDevice(&check);
if(status < 0){
return status;
}
break;
}
SCPopContext(self->pOwner);
}
status = LLDnodePtr2Next(self->iList);
}
if (isCounting) {
if (isDriving) {
SetStatus(eCountDrive);
} else {
SetStatus(eCounting);
}
} else if (isDriving) {
SetStatus(eDriving);
}
iRet = LLDnodePtr2First(self->iList);
return testFinish(self);
}
/*---------------------------------------------------------------------------*/
int Wait4Success(pExeList self)
{