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
This commit is contained in:
2014-10-13 13:36:37 +02:00
parent 8ea20b87f4
commit b319461531
8 changed files with 155 additions and 135 deletions

View File

@ -543,6 +543,7 @@ void DeleteInterp(SicsInterp * self)
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05 call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
*/ */
Tcl_DeleteInterp(pTcl);
KillSicsUnknown(); KillSicsUnknown();
} }

3
cone.c
View File

@ -171,7 +171,6 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
*/ */
SICSHdbGetPar(obj, pCon, "target", &v); SICSHdbGetPar(obj, pCon, "target", &v);
target.h = v.v.floatArray[0]; target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2]; target.l = v.v.floatArray[2];
SICSHdbGetPar(obj, pCon, "qscale", &v); SICSHdbGetPar(obj, pCon, "qscale", &v);
/* /*
@ -198,7 +197,7 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
mat_free(csToPsi); mat_free(csToPsi);
if (status != 1) { if (status != 1) {
SCWrite(pCon, "ERROR: cannot get cone vector into scattering position", SCWrite(pCon, "ERROR: cannot get cone vector into scattering position",
eError); eLogError);
SCSetInterrupt(pCon, eAbortOperation); SCSetInterrupt(pCon, eAbortOperation);
return 0; return 0;
} }

View File

@ -182,12 +182,13 @@ pExeList CreateExeList(pTaskMan pTask)
pRes->waitID = -1; pRes->waitID = -1;
pRes->runID = -1; pRes->runID = -1;
pRes->iLock = 0; pRes->iLock = 0;
pRes->drivePrint = 0; pRes->drivePrint = 0;
pRes->paused = 0; pRes->paused = 0;
pRes->taskRunning = 0; pRes->taskRunning = 0;
pRes->pCall = CreateCallBackInterface(); pRes->pCall = CreateCallBackInterface();
pRes->lastRun = time(NULL); pRes->lastRun = time(NULL);
pRes->pDes->GetInterface = DevexecInterface; pRes->pDes->GetInterface = DevexecInterface;
pRes->instStatus = eEager;
return pRes; return pRes;
} }

View File

@ -126,6 +126,9 @@ static int HMCStatus(void *pData, SConnection * pCon)
assert(self); assert(self);
if(self->checkSlaves == 0) { if(self->checkSlaves == 0) {
/*
check master
*/
status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon); status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon);
/* /*
Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories. Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories.
@ -194,7 +197,7 @@ static int HMCBoaStatus(void *pData, SConnection * pCon)
HMCHalt(self); HMCHalt(self);
ReleaseCountLock(self->pCount); ReleaseCountLock(self->pCount);
self->checkSlaves = 0; self->checkSlaves = 0;
for(j = 0; j < 100; j++){ for(j = 0; j < 200; j++){
SicsWait(1); SicsWait(1);
status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon); status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon);
if(status == HWIdle || status == HWFault) { if(status == HWIdle || status == HWFault) {

View File

@ -196,6 +196,7 @@ static void KillDriveTaskData(void *data)
if(taskData->pCon != NULL){ if(taskData->pCon != NULL){
SCDeleteConnection(taskData->pCon); SCDeleteConnection(taskData->pCon);
} }
free(taskData);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void DriveTaskSignal(void *data, int iSignal, void *pSigData) static void DriveTaskSignal(void *data, int iSignal, void *pSigData)
@ -240,6 +241,7 @@ static int DriveTaskFunc(void *data)
} else { } else {
ExeInterest(pServ->pExecutor,taskData->name, "finished with problem"); ExeInterest(pServ->pExecutor,taskData->name, "finished with problem");
} }
traceSys("drive","DriveTask %s finished with state %d", taskData->name,status);
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -338,6 +340,7 @@ static void KillCountTaskData(void *data)
if(taskData->pCon != NULL){ if(taskData->pCon != NULL){
SCDeleteConnection(taskData->pCon); SCDeleteConnection(taskData->pCon);
} }
free(taskData);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void CountTaskSignal(void *data, int iSignal, void *pSigData) static void CountTaskSignal(void *data, int iSignal, void *pSigData)
@ -389,6 +392,7 @@ static int CountTaskFunc(void *data)
} else { } else {
ExeInterest(pServ->pExecutor,taskData->name, "finished with problem"); ExeInterest(pServ->pExecutor,taskData->name, "finished with problem");
} }
traceSys("count","CountTask %s finished with state %d", taskData->name,status);
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/

View File

@ -239,7 +239,7 @@ static hdbCallbackReturn MultiSecControllCallback(pHdb node,
return hdbContinue; return hdbContinue;
} }
/*--------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------2-*/
static int MultiSecTransfer(void *pData, SConnection * pCon) static int MultiSecTransfer(void *pData, SConnection * pCon)
{ {
int i, retVal = OKOK, tclStatus; int i, retVal = OKOK, tclStatus;
@ -253,6 +253,7 @@ static int MultiSecTransfer(void *pData, SConnection * pCon)
transfer = GetHipadabaNode(pCount->objectNode,"transfer"); transfer = GetHipadabaNode(pCount->objectNode,"transfer");
if(transfer != NULL){ if(transfer != NULL){
myCon = SCCopyConnection(pCon); myCon = SCCopyConnection(pCon);
SCsetMacro(myCon,1);
MacroPush(myCon); MacroPush(myCon);
tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text); tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text);
if (tclStatus != TCL_OK) { if (tclStatus != TCL_OK) {
@ -269,140 +270,139 @@ static int MultiSecTransfer(void *pData, SConnection * pCon)
return retVal; return retVal;
} }
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status) static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
{ {
pHdb mID, master, myStatus, control, ccd, stopTime, timeNode; pHdb mID, master, myStatus, control, ccd, stopTime, timeNode;
hdbValue v; hdbValue v;
long mlID; long mlID;
void *data; void *data;
pICountable pCount; pICountable pCount;
float controlVal, tVal; float controlVal, tVal;
MonEvent sMon; MonEvent sMon;
mID = GetHipadabaNode(self->objectNode,"masterID"); mID = GetHipadabaNode(self->objectNode,"masterID");
master = GetHipadabaNode(self->objectNode,"master"); master = GetHipadabaNode(self->objectNode,"master");
myStatus = GetHipadabaNode(self->objectNode,"status"); myStatus = GetHipadabaNode(self->objectNode,"status");
control = GetHipadabaNode(self->objectNode,"control"); control = GetHipadabaNode(self->objectNode,"control");
ccd = GetHipadabaNode(self->objectNode,"ccd"); ccd = GetHipadabaNode(self->objectNode,"ccd");
stopTime = GetHipadabaNode(self->objectNode,"stopTime"); stopTime = GetHipadabaNode(self->objectNode,"stopTime");
timeNode = GetHipadabaNode(self->objectNode,"time"); timeNode = GetHipadabaNode(self->objectNode,"time");
assert(mID != NULL); assert(mID != NULL);
assert(master != NULL); assert(master != NULL);
assert(myStatus != NULL); assert(myStatus != NULL);
assert(control != NULL); assert(control != NULL);
assert(ccd != NULL); assert(ccd != NULL);
assert(stopTime != NULL); assert(stopTime != NULL);
assert(timeNode != NULL); assert(timeNode != NULL);
mlID = mID->value.v.intValue; mlID = mID->value.v.intValue;
if(mlID == 0) { if(mlID == 0) {
return 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++;
} }
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"); data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
myStatus = GetHipadabaNode(self->objectNode,"status"); assert(data != NULL);
stopTime = GetHipadabaNode(self->objectNode,"stopTime"); pCount = GetCountableInterface(data);
ccd = GetHipadabaNode(self->objectNode,"ccd"); assert(pCount != NULL);
assert(slaveID != NULL);
assert(myStatus != NULL);
assert(stopTime != NULL);
assert(ccd != NULL);
if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){ if(isTaskIDRunning(pServ->pTasker,mlID)) {
if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) { *status = pCount->CheckCountStatus(data,pCon);
SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError); controlVal = GetControlValue((pCounter)data);
self->pCountInt->Halt(self); UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon);
ReleaseCountLock(self->pCountInt); tVal = GetCountTime((pCounter)data,pCon);
for(i = 0; i < 100; i++){ UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
SicsWait(1); SecCounterSetError(self,"None");
if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){ switch(*status){
self->pCountInt->StartCount(self,pCon); case HWFault:
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon);
UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),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; *status = HWBusy;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
return 1; return 1;
} }
} } else {
SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError); *status = HWIdle;
*status = HWFault; UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon);
return 0; return 0;
} else { }
*status = HWBusy; return 1;
UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon); }
return 1;
}
} else {
*status = HWIdle;
UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon);
return 0;
}
return 1;
}
/*------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------*/
static void multiEndCounting(pCounter self, SConnection *pCon) static void multiEndCounting(pCounter self, SConnection *pCon)
{ {

View File

@ -235,6 +235,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self,
SCWrite(pCon, buffer, eError); SCWrite(pCon, buffer, eError);
return -1; return -1;
} }
traceIO("datafile", "Opening %s", argv[2]);
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} }
@ -1499,7 +1500,7 @@ static int SPutPadding(void *message, void *userData)
{ {
pPutMessage self = (pPutMessage)message; pPutMessage self = (pPutMessage)message;
char *pPtr = NULL, *pEnd = NULL; 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){ if(self->v.dataType == HIPTEXT && strstr(self->v.v.text,"@len") != NULL){
pPtr = strchr(self->v.v.text,'='); pPtr = strchr(self->v.v.text,'=');
@ -1509,11 +1510,11 @@ static int SPutPadding(void *message, void *userData)
*pEnd = '\0'; *pEnd = '\0';
len = atoi(pPtr); len = atoi(pPtr);
} }
pPtr = malloc((len+5)*sizeof(char)); pPtr = malloc((len+7)*sizeof(char));
if(pPtr != NULL){ if(pPtr != NULL){
memset(pPtr,0,len*sizeof(char)); memset(pPtr,0,len*sizeof(char));
strncpy(pPtr,pEnd+1,len); strncpy(pPtr,pEnd+1,len);
for(i = strlen(pPtr); i < len-1; i++){ for(i = strlen(pPtr); i < len-2; i++){
pPtr[i] = ' '; pPtr[i] = ' ';
} }
pPtr[len-1] = '!'; pPtr[len-1] = '!';
@ -1550,7 +1551,11 @@ static int SPutDim(void *message, void *userData)
self->dim[0] = self->v.arrayLength; self->dim[0] = self->v.arrayLength;
break; break;
case HIPTEXT: 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; break;
default: default:
snprintf(self->error, sizeof(self->error),"invalid data type %d", snprintf(self->error, sizeof(self->error),"invalid data type %d",

View File

@ -8,6 +8,13 @@
* copyright: see file COPYRIGHT * copyright: see file COPYRIGHT
* *
* Mark Koennecke, February 2013 * 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 <sics.h> #include <sics.h>
#include "tasmono.h" #include "tasmono.h"