- Added log instrumentation to devexe
- Added a hill climbing option to optimise - Added hrpt files SKIPPED: psi/libpsi.a psi/sinqhmdriv.c psi/tabledrive.c
This commit is contained in:
240
devexec.c
240
devexec.c
@ -42,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"
|
||||
@ -56,11 +58,51 @@
|
||||
#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;
|
||||
@ -122,6 +164,7 @@ typedef struct {
|
||||
int iLock;
|
||||
pICallBack pCall;
|
||||
time_t lastRun;
|
||||
int paused;
|
||||
} ExeList;
|
||||
|
||||
static pExeList pExecutor = NULL;
|
||||
@ -178,6 +221,10 @@ typedef struct {
|
||||
|
||||
free(self);
|
||||
pServ->pExecutor = NULL;
|
||||
if(devLog != NULL){
|
||||
fclose(devLog);
|
||||
devLog = NULL;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
|
||||
@ -295,6 +342,7 @@ typedef struct {
|
||||
self->iEnd = 0;
|
||||
pCon->conStatus = HWBusy;
|
||||
}
|
||||
DevexecLog("START",pNew->name);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -397,7 +445,7 @@ typedef struct {
|
||||
pCon,pCter->pDriv->fPreset);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int CheckExeList(pExeList self)
|
||||
int CheckExeListOld(pExeList self)
|
||||
{
|
||||
int iRet;
|
||||
pDevEntry pDev = NULL;
|
||||
@ -568,6 +616,196 @@ typedef struct {
|
||||
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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user