From b3194615311d5fdbcabcbb7b1fd5cfc88d6861e8 Mon Sep 17 00:00:00 2001 From: Mark Koennecke Date: Mon, 13 Oct 2014 13:36:37 +0200 Subject: [PATCH] Fixed a minor memory leak in count and drive task handling Reformatted multicountser to become clearer Minor fixes Added more tracing output to sort the SANSLI problem --- SCinter.c | 1 + cone.c | 3 +- devexec.c | 3 +- hmcontrol.c | 5 +- interface.c | 4 + multicountersec.c | 254 +++++++++++++++++++++++----------------------- nxscript.c | 13 ++- tasmono.c | 7 ++ 8 files changed, 155 insertions(+), 135 deletions(-) diff --git a/SCinter.c b/SCinter.c index 326803d2..1d5cd1a4 100644 --- a/SCinter.c +++ b/SCinter.c @@ -543,6 +543,7 @@ void DeleteInterp(SicsInterp * self) call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05 */ + Tcl_DeleteInterp(pTcl); KillSicsUnknown(); } diff --git a/cone.c b/cone.c index b90279ca..9ac2e252 100644 --- a/cone.c +++ b/cone.c @@ -171,7 +171,6 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal) */ SICSHdbGetPar(obj, pCon, "target", &v); target.h = v.v.floatArray[0]; - target.k = v.v.floatArray[1]; target.l = v.v.floatArray[2]; SICSHdbGetPar(obj, pCon, "qscale", &v); /* @@ -198,7 +197,7 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal) mat_free(csToPsi); if (status != 1) { SCWrite(pCon, "ERROR: cannot get cone vector into scattering position", - eError); + eLogError); SCSetInterrupt(pCon, eAbortOperation); return 0; } diff --git a/devexec.c b/devexec.c index 86e0f12f..3ca44665 100644 --- a/devexec.c +++ b/devexec.c @@ -182,12 +182,13 @@ pExeList CreateExeList(pTaskMan pTask) pRes->waitID = -1; pRes->runID = -1; pRes->iLock = 0; - pRes->drivePrint = 0; + pRes->drivePrint = 0; pRes->paused = 0; pRes->taskRunning = 0; pRes->pCall = CreateCallBackInterface(); pRes->lastRun = time(NULL); pRes->pDes->GetInterface = DevexecInterface; + pRes->instStatus = eEager; return pRes; } diff --git a/hmcontrol.c b/hmcontrol.c index aed00d55..dd0e22fe 100644 --- a/hmcontrol.c +++ b/hmcontrol.c @@ -126,6 +126,9 @@ static int HMCStatus(void *pData, SConnection * pCon) assert(self); if(self->checkSlaves == 0) { + /* + check master + */ status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon); /* Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories. @@ -194,7 +197,7 @@ static int HMCBoaStatus(void *pData, SConnection * pCon) HMCHalt(self); ReleaseCountLock(self->pCount); self->checkSlaves = 0; - for(j = 0; j < 100; j++){ + for(j = 0; j < 200; j++){ SicsWait(1); status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon); if(status == HWIdle || status == HWFault) { diff --git a/interface.c b/interface.c index ee597677..d661b2c3 100644 --- a/interface.c +++ b/interface.c @@ -196,6 +196,7 @@ static void KillDriveTaskData(void *data) if(taskData->pCon != NULL){ SCDeleteConnection(taskData->pCon); } + free(taskData); } /*-------------------------------------------------------------------------*/ static void DriveTaskSignal(void *data, int iSignal, void *pSigData) @@ -240,6 +241,7 @@ static int DriveTaskFunc(void *data) } else { ExeInterest(pServ->pExecutor,taskData->name, "finished with problem"); } + traceSys("drive","DriveTask %s finished with state %d", taskData->name,status); return 0; } /*--------------------------------------------------------------------------*/ @@ -338,6 +340,7 @@ static void KillCountTaskData(void *data) if(taskData->pCon != NULL){ SCDeleteConnection(taskData->pCon); } + free(taskData); } /*-------------------------------------------------------------------------*/ static void CountTaskSignal(void *data, int iSignal, void *pSigData) @@ -389,6 +392,7 @@ static int CountTaskFunc(void *data) } else { ExeInterest(pServ->pExecutor,taskData->name, "finished with problem"); } + traceSys("count","CountTask %s finished with state %d", taskData->name,status); return 0; } /*--------------------------------------------------------------------------*/ diff --git a/multicountersec.c b/multicountersec.c index 71687a9b..c94b2c0f 100644 --- a/multicountersec.c +++ b/multicountersec.c @@ -239,7 +239,7 @@ static hdbCallbackReturn MultiSecControllCallback(pHdb node, return hdbContinue; } -/*--------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------2-*/ static int MultiSecTransfer(void *pData, SConnection * pCon) { int i, retVal = OKOK, tclStatus; @@ -253,6 +253,7 @@ static int MultiSecTransfer(void *pData, SConnection * pCon) transfer = GetHipadabaNode(pCount->objectNode,"transfer"); if(transfer != NULL){ myCon = SCCopyConnection(pCon); + SCsetMacro(myCon,1); MacroPush(myCon); tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text); if (tclStatus != TCL_OK) { @@ -269,140 +270,139 @@ static int MultiSecTransfer(void *pData, SConnection * pCon) return retVal; } /*-------------------------------------------------------------------------------------*/ -static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status) -{ - pHdb mID, master, myStatus, control, ccd, stopTime, timeNode; - hdbValue v; - long mlID; - void *data; - pICountable pCount; - float controlVal, tVal; - MonEvent sMon; + static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status) + { + pHdb mID, master, myStatus, control, ccd, stopTime, timeNode; + hdbValue v; + long mlID; + void *data; + pICountable pCount; + float controlVal, tVal; + MonEvent sMon; - mID = GetHipadabaNode(self->objectNode,"masterID"); - master = GetHipadabaNode(self->objectNode,"master"); - myStatus = GetHipadabaNode(self->objectNode,"status"); - control = GetHipadabaNode(self->objectNode,"control"); - ccd = GetHipadabaNode(self->objectNode,"ccd"); - stopTime = GetHipadabaNode(self->objectNode,"stopTime"); - timeNode = GetHipadabaNode(self->objectNode,"time"); - assert(mID != NULL); - assert(master != NULL); - assert(myStatus != NULL); - assert(control != NULL); - assert(ccd != NULL); - assert(stopTime != NULL); - assert(timeNode != NULL); - + mID = GetHipadabaNode(self->objectNode,"masterID"); + master = GetHipadabaNode(self->objectNode,"master"); + myStatus = GetHipadabaNode(self->objectNode,"status"); + control = GetHipadabaNode(self->objectNode,"control"); + ccd = GetHipadabaNode(self->objectNode,"ccd"); + stopTime = GetHipadabaNode(self->objectNode,"stopTime"); + timeNode = GetHipadabaNode(self->objectNode,"time"); + assert(mID != NULL); + assert(master != NULL); + assert(myStatus != NULL); + assert(control != NULL); + assert(ccd != NULL); + assert(stopTime != NULL); + assert(timeNode != NULL); + - mlID = mID->value.v.intValue; - if(mlID == 0) { - return 0; - } - - data = FindCommandData(pServ->pSics,master->value.v.text,NULL); - assert(data != NULL); - pCount = GetCountableInterface(data); - assert(pCount != NULL); - - if(isTaskIDRunning(pServ->pTasker,mlID)) { - *status = pCount->CheckCountStatus(data,pCon); - controlVal = GetControlValue((pCounter)data); - UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon); - tVal = GetCountTime((pCounter)data,pCon); - UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon); - SecCounterSetError(self,"None"); - switch(*status){ - case HWFault: - UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon); - UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); - SecCounterSetError(self,"Master counter errror"); - *status = HWBusy; - break; - case HWPause: - UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon); - *status = HWPause; - break; - case HWNoBeam: - UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon); - *status = HWNoBeam; - break; - default: - *status = HWBusy; - UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); - if (self->iCallbackCounter > 20) { - MultiSecTransfer(self,pCon); - sMon.fCurrent = controlVal; - sMon.fPreset = GetCounterPreset(self); - sMon.pName = self->name; - InvokeCallBack(self->pCall, MONITOR, &sMon); - self->iCallbackCounter = 0; - } else { - self->iCallbackCounter++; + mlID = mID->value.v.intValue; + if(mlID == 0) { + return 0; } - break; - } - } else { - /* - we recently stopped. Mark it so and stop slaves. - */ - mID->value.v.intValue = 0; - *status = HWBusy; - UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); - UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); - tVal = GetCountTime((pCounter)data,pCon); - UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon); - if(ccd->value.v.intValue != 1) { - doCountCommand(self->objectNode,pCon,1011); - } - } - return 1; -} -/*-------------------------------------------------------------------------------------*/ -static int areSlavesRunning(pCounter self, SConnection *pCon, int *status) -{ - pHdb slaveID, myStatus, stopTime, ccd; - int i; - slaveID = GetHipadabaNode(self->objectNode,"slaveID"); - myStatus = GetHipadabaNode(self->objectNode,"status"); - stopTime = GetHipadabaNode(self->objectNode,"stopTime"); - ccd = GetHipadabaNode(self->objectNode,"ccd"); - assert(slaveID != NULL); - assert(myStatus != NULL); - assert(stopTime != NULL); - assert(ccd != NULL); + data = FindCommandData(pServ->pSics,master->value.v.text,NULL); + assert(data != NULL); + pCount = GetCountableInterface(data); + assert(pCount != NULL); - if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){ - if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) { - SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError); - self->pCountInt->Halt(self); - ReleaseCountLock(self->pCountInt); - for(i = 0; i < 100; i++){ - SicsWait(1); - if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){ - self->pCountInt->StartCount(self,pCon); - UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); - UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); + if(isTaskIDRunning(pServ->pTasker,mlID)) { + *status = pCount->CheckCountStatus(data,pCon); + controlVal = GetControlValue((pCounter)data); + UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon); + tVal = GetCountTime((pCounter)data,pCon); + UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon); + SecCounterSetError(self,"None"); + switch(*status){ + case HWFault: + UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon); + UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); + SecCounterSetError(self,"Master counter errror"); + *status = HWBusy; + break; + case HWPause: + UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon); + *status = HWPause; + break; + case HWNoBeam: + UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon); + *status = HWNoBeam; + break; + default: + *status = HWBusy; + UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); + if (self->iCallbackCounter > 20) { + MultiSecTransfer(self,pCon); + sMon.fCurrent = controlVal; + sMon.fPreset = GetCounterPreset(self); + sMon.pName = self->name; + InvokeCallBack(self->pCall, MONITOR, &sMon); + self->iCallbackCounter = 0; + } else { + self->iCallbackCounter++; + } + break; + } + } else { + /* + we recently stopped. Mark it so and stop slaves. + */ + mID->value.v.intValue = 0; + *status = HWBusy; + UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); + UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); + tVal = GetCountTime((pCounter)data,pCon); + UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon); + if(ccd->value.v.intValue != 1) { + doCountCommand(self->objectNode,pCon,1011); + } + } + return 1; + } + /*-------------------------------------------------------------------------------------*/ + static int areSlavesRunning(pCounter self, SConnection *pCon, int *status) + { + pHdb slaveID, myStatus, stopTime, ccd; + int i; + + slaveID = GetHipadabaNode(self->objectNode,"slaveID"); + myStatus = GetHipadabaNode(self->objectNode,"status"); + stopTime = GetHipadabaNode(self->objectNode,"stopTime"); + ccd = GetHipadabaNode(self->objectNode,"ccd"); + assert(slaveID != NULL); + assert(myStatus != NULL); + assert(stopTime != NULL); + assert(ccd != NULL); + + if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){ + if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) { + SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError); + self->pCountInt->Halt(self); + ReleaseCountLock(self->pCountInt); + for(i = 0; i < 100; i++){ + SicsWait(1); + if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){ + self->pCountInt->StartCount(self,pCon); + UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); + UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon); + *status = HWBusy; + return 1; + } + } + SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError); + *status = HWFault; + } else { *status = HWBusy; + UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); return 1; } - } - SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError); - *status = HWFault; - return 0; - } else { - *status = HWBusy; - UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); - return 1; - } -} else { - *status = HWIdle; - UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon); - return 0; -} -return 1; -} + } else { + *status = HWIdle; + UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon); + return 0; + } + return 1; + } /*------------------------------------------------------------------------------------*/ static void multiEndCounting(pCounter self, SConnection *pCon) { diff --git a/nxscript.c b/nxscript.c index 298d0dbb..ef31f14f 100644 --- a/nxscript.c +++ b/nxscript.c @@ -235,6 +235,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self, SCWrite(pCon, buffer, eError); return -1; } + traceIO("datafile", "Opening %s", argv[2]); SCSendOK(pCon); return 1; } @@ -1499,7 +1500,7 @@ static int SPutPadding(void *message, void *userData) { pPutMessage self = (pPutMessage)message; char *pPtr = NULL, *pEnd = NULL; - unsigned int len, i; + unsigned int len = 0, i; if(self->v.dataType == HIPTEXT && strstr(self->v.v.text,"@len") != NULL){ pPtr = strchr(self->v.v.text,'='); @@ -1509,11 +1510,11 @@ static int SPutPadding(void *message, void *userData) *pEnd = '\0'; len = atoi(pPtr); } - pPtr = malloc((len+5)*sizeof(char)); + pPtr = malloc((len+7)*sizeof(char)); if(pPtr != NULL){ memset(pPtr,0,len*sizeof(char)); strncpy(pPtr,pEnd+1,len); - for(i = strlen(pPtr); i < len-1; i++){ + for(i = strlen(pPtr); i < len-2; i++){ pPtr[i] = ' '; } pPtr[len-1] = '!'; @@ -1550,7 +1551,11 @@ static int SPutDim(void *message, void *userData) self->dim[0] = self->v.arrayLength; break; case HIPTEXT: - self->dim[0] = strlen(self->v.v.text)+1; + if(self->v.v.text != NULL){ + self->dim[0] = strlen(self->v.v.text)+1; + } else { + self->dim[0] = 1; + } break; default: snprintf(self->error, sizeof(self->error),"invalid data type %d", diff --git a/tasmono.c b/tasmono.c index f538d989..0129d6ae 100644 --- a/tasmono.c +++ b/tasmono.c @@ -8,6 +8,13 @@ * copyright: see file COPYRIGHT * * Mark Koennecke, February 2013 + * + * TODO: this may need a refactoring towards a monochromator object with its + * own parameters and such. Eiger would have benefitted from this. This here + * just implements a drivable interface on top of the tasub parameters. As EIGER + * is now working; this has gone low priority. + * + * Mark Koennecke, September 2014 */ #include #include "tasmono.h"