- Added bridge functions to histmemsec to make it look more like histmem
- Modifed many modules using histmem to work also with histmemsec - Extended tasker with task names and task groups - There is a new taskobj which allows to list tasks and to interact with them. - Task now supports running Tcl functions as tasks - There is a new experimental sctcomtask module which allows to define communication tasks against a scriptcontext. This is a new feature which should facilitate writing sequential scripts using asynchronous communication. - A fix to make spss7 work when there are no switches - ORION support for single X. TRICS measures crystals hanging down, ORION standing up SKIPPED: psi/ease.c psi/faverage.c psi/jvlprot.c psi/make_gen psi/pardef.c psi/polterwrite.c psi/psi.c psi/sinq.c psi/spss7.c
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 467 "histogram.w"
|
#line 470 "histogram.w"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
H I S T D R I V
|
H I S T D R I V
|
||||||
@ -72,7 +72,7 @@
|
|||||||
void *pPriv;
|
void *pPriv;
|
||||||
} HistDriver;
|
} HistDriver;
|
||||||
|
|
||||||
#line 479 "histogram.w"
|
#line 482 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#line 232 "histogram.w"
|
#line 232 "histogram.w"
|
||||||
@ -84,7 +84,7 @@
|
|||||||
HistInt *DefaultSubSample(pHistDriver self, SConnection *pCon,
|
HistInt *DefaultSubSample(pHistDriver self, SConnection *pCon,
|
||||||
int bank, char *command);
|
int bank, char *command);
|
||||||
|
|
||||||
#line 480 "histogram.w"
|
#line 483 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
82
HistMem.h
82
HistMem.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 440 "histogram.w"
|
#line 443 "histogram.w"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
H I S T M E M
|
H I S T M E M
|
||||||
@ -13,17 +13,17 @@
|
|||||||
#define SICSHISTMEM
|
#define SICSHISTMEM
|
||||||
#define MAXDIM 3
|
#define MAXDIM 3
|
||||||
|
|
||||||
typedef struct __HistDriver *pHistDriver;
|
typedef struct __HistDriver *pHistDriver;
|
||||||
typedef struct __HistMem *pHistMem;
|
typedef struct __HistMem *pHistMem;
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
typedef int HistInt;
|
typedef int HistInt;
|
||||||
/*
|
/*
|
||||||
32 bit integer on a DigitalUnix
|
32 bit integer on a DigitalUnix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#line 9 "histogram.w"
|
#line 9 "histogram.w"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eHTransparent,
|
eHTransparent,
|
||||||
eHNormal,
|
eHNormal,
|
||||||
eHTOF,
|
eHTOF,
|
||||||
@ -31,71 +31,73 @@ typedef enum {
|
|||||||
eHRPT,
|
eHRPT,
|
||||||
ePSD,
|
ePSD,
|
||||||
eSANSTOF
|
eSANSTOF
|
||||||
} HistMode;
|
} HistMode;
|
||||||
|
|
||||||
#line 36 "histogram.w"
|
#line 36 "histogram.w"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eOIgnore,
|
eOIgnore,
|
||||||
eOCeil,
|
eOCeil,
|
||||||
eOCount,
|
eOCount,
|
||||||
eReflect
|
eReflect
|
||||||
} OverFlowMode;
|
} OverFlowMode;
|
||||||
|
|
||||||
#line 460 "histogram.w"
|
#line 463 "histogram.w"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#line 292 "histogram.w"
|
#line 292 "histogram.w"
|
||||||
|
|
||||||
pHistMem CreateHistMemory(char *drivername);
|
pHistMem CreateHistMemory(char *drivername);
|
||||||
void DeleteHistMemory(void *self);
|
void DeleteHistMemory(void *self);
|
||||||
|
|
||||||
#line 308 "histogram.w"
|
#line 308 "histogram.w"
|
||||||
|
|
||||||
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
|
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
|
||||||
int HistSetOption(pHistMem self, char *name, char *value);
|
int HistSetOption(pHistMem self, char *name, char *value);
|
||||||
int HistConfigure(pHistMem self, SConnection * pCon, SicsInterp * pSics);
|
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
|
||||||
|
|
||||||
#line 336 "histogram.w"
|
#line 336 "histogram.w"
|
||||||
|
|
||||||
float GetHistPreset(pHistMem self);
|
float GetHistPreset(pHistMem self);
|
||||||
int SetHistPreset(pHistMem self, float fVal);
|
int SetHistPreset(pHistMem self, float fVal);
|
||||||
CounterMode GetHistCountMode(pHistMem self);
|
CounterMode GetHistCountMode(pHistMem self);
|
||||||
int SetHistCountMode(pHistMem self, CounterMode eNew);
|
int SetHistCountMode(pHistMem self, CounterMode eNew);
|
||||||
long GetHistMonitor(pHistMem self, int i, SConnection * pCon);
|
long GetHistMonitor(pHistMem self, int i, SConnection *pCon);
|
||||||
const float *GetHistTimeBin(pHistMem self, int *iLength);
|
const float *GetHistTimeBin(pHistMem self, int *iLength);
|
||||||
int GetHistLength(pHistMem self);
|
int GetHistLength(pHistMem self);
|
||||||
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);
|
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);
|
||||||
float GetHistCountTime(pHistMem self, SConnection * pCon);
|
float GetHistCountTime(pHistMem self,SConnection *pCon);
|
||||||
int HistDoCount(pHistMem self, SConnection * pCon);
|
int HistDoCount(pHistMem self, SConnection *pCon);
|
||||||
int HistBlockCount(pHistMem self, SConnection * pCon);
|
int HistBlockCount(pHistMem self, SConnection *pCon);
|
||||||
void HistDirty(pHistMem self);
|
void HistDirty(pHistMem self);
|
||||||
|
|
||||||
|
int isSecondGen(pHistMem self);
|
||||||
|
pHistMem FindHM(SicsInterp *pSics, char *name);
|
||||||
|
|
||||||
|
|
||||||
#line 366 "histogram.w"
|
#line 369 "histogram.w"
|
||||||
|
|
||||||
int SetHistogram(pHistMem self, SConnection * pCon,
|
int SetHistogram(pHistMem self, SConnection *pCon,
|
||||||
int i, int iStart, int iEnd, HistInt * lData);
|
int i,int iStart, int iEnd, HistInt *lData);
|
||||||
int GetHistogram(pHistMem self, SConnection * pCon,
|
int GetHistogram(pHistMem self, SConnection *pCon,
|
||||||
int i, int iStart, int iEnd, HistInt * lData,
|
int i,int iStart, int iEnd, HistInt *lData, int iDataLen);
|
||||||
int iDataLen);
|
HistInt *GetHistogramPointer(pHistMem self,SConnection *pCon);
|
||||||
HistInt *GetHistogramPointer(pHistMem self, SConnection * pCon);
|
int GetHistogramDirect(pHistMem self, SConnection *pCon,
|
||||||
int GetHistogramDirect(pHistMem self, SConnection * pCon,
|
|
||||||
int i, int iStart, int iEnd,
|
int i, int iStart, int iEnd,
|
||||||
HistInt * lData, int iDataLen);
|
HistInt *lData, int iDataLen);
|
||||||
int PresetHistogram(pHistMem self, SConnection * pCon, HistInt lVal);
|
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);
|
||||||
|
|
||||||
#line 409 "histogram.w"
|
#line 412 "histogram.w"
|
||||||
|
|
||||||
int MakeHistMemory(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
#line 462 "histogram.w"
|
#line 465 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 485 "histogram.w"
|
#line 488 "histogram.w"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
H I S T M E M -- Internal
|
H I S T M E M -- Internal
|
||||||
@ -23,7 +23,7 @@
|
|||||||
pICallBack pCall;
|
pICallBack pCall;
|
||||||
} HistMem;
|
} HistMem;
|
||||||
|
|
||||||
#line 495 "histogram.w"
|
#line 498 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -273,7 +273,7 @@ static int TclExecFunc(SConnection *pCon, SicsInterp *pInter, void *data,
|
|||||||
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
|
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
|
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eError );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ int BackgroundCommand(SConnection * pCon, char *command)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskRegister(pServ->pTasker, BackgroundTask, NULL, KillBckTask, self, 1);
|
TaskRegisterN(pServ->pTasker, self->command, BackgroundTask, NULL, KillBckTask, self, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
SCWrite(pCon, "ERROR: autologging is already active", eError);
|
SCWrite(pCon, "ERROR: autologging is already active", eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
TaskRegister(pServ->pTasker, AutoTask, NULL, NULL, NULL, 1);
|
TaskRegisterN(pServ->pTasker, "autologger", AutoTask, NULL, NULL, NULL, 1);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
iAutoActive = 1;
|
iAutoActive = 1;
|
||||||
return 1;
|
return 1;
|
||||||
|
2
conman.c
2
conman.c
@ -1167,7 +1167,7 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
|
|||||||
compStream.avail_in = iDataLen;
|
compStream.avail_in = iDataLen;
|
||||||
compStream.avail_out = iDataLen;
|
compStream.avail_out = iDataLen;
|
||||||
iRet = deflate(&compStream, Z_FINISH);
|
iRet = deflate(&compStream, Z_FINISH);
|
||||||
if (iRet != Z_STREAM_END) {
|
if (iRet != Z_STREAM_END && iRet != Z_OK) {
|
||||||
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
||||||
SCWrite(self, outBuf, eError);
|
SCWrite(self, outBuf, eError);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -30,6 +30,8 @@ typedef struct __Counter{
|
|||||||
int iCallbackCounter;
|
int iCallbackCounter;
|
||||||
int badStatusCount;
|
int badStatusCount;
|
||||||
int haltFixFlag; /* solely here to prevent multiple calls to the halt function on overrun timers in countersec.c*/
|
int haltFixFlag; /* solely here to prevent multiple calls to the halt function on overrun timers in countersec.c*/
|
||||||
|
int tbLength; /* These two for caching float time bins in second generation HM's */
|
||||||
|
float *timeBinning;
|
||||||
int (*setMode)(struct __Counter *self, CounterMode eMode);
|
int (*setMode)(struct __Counter *self, CounterMode eMode);
|
||||||
CounterMode (*getMode)(struct __Counter *self);
|
CounterMode (*getMode)(struct __Counter *self);
|
||||||
int (*getNMonitor)(struct __Counter *self);
|
int (*getNMonitor)(struct __Counter *self);
|
||||||
|
12
devexec.c
12
devexec.c
@ -376,7 +376,7 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
|||||||
self->iStatus = DEVDONE;
|
self->iStatus = DEVDONE;
|
||||||
/* if no task: start it */
|
/* if no task: start it */
|
||||||
if (self->lTask < 0) {
|
if (self->lTask < 0) {
|
||||||
self->lTask = TaskRegister(self->pTask,
|
self->lTask = TaskRegisterN(self->pTask,"devexec",
|
||||||
DevExecTask,
|
DevExecTask,
|
||||||
DevExecSignal, NULL, self, 1);
|
DevExecSignal, NULL, self, 1);
|
||||||
self->iEnd = 0;
|
self->iEnd = 0;
|
||||||
@ -476,7 +476,7 @@ static int ForceStartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
|||||||
self->iStatus = DEVDONE;
|
self->iStatus = DEVDONE;
|
||||||
/* if no task: start it */
|
/* if no task: start it */
|
||||||
if (self->lTask < 0) {
|
if (self->lTask < 0) {
|
||||||
self->lTask = TaskRegister(self->pTask,
|
self->lTask = TaskRegisterN(self->pTask,"devexec",
|
||||||
DevExecTask,
|
DevExecTask,
|
||||||
DevExecSignal, NULL, self, 1);
|
DevExecSignal, NULL, self, 1);
|
||||||
self->iEnd = 0;
|
self->iEnd = 0;
|
||||||
@ -962,12 +962,20 @@ int StopByData(pExeList self, void *data)
|
|||||||
} else if (pCountInt) {
|
} else if (pCountInt) {
|
||||||
pCountInt->Halt(pDev->pData);
|
pCountInt->Halt(pDev->pData);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
This is wrong: most devices will require some time
|
||||||
|
before they really stop. CheckExeList has to run...
|
||||||
|
This causes core dumps......
|
||||||
|
|
||||||
|
Mark
|
||||||
|
|
||||||
ExeInterest(self, pDev, "finished");
|
ExeInterest(self, pDev, "finished");
|
||||||
DevexecLog("FINISHED", pDev->name);
|
DevexecLog("FINISHED", pDev->name);
|
||||||
DeleteDevEntry(pDev);
|
DeleteDevEntry(pDev);
|
||||||
LLDnodeDelete(self->iList);
|
LLDnodeDelete(self->iList);
|
||||||
self->iStatus = DEVDONE;
|
self->iStatus = DEVDONE;
|
||||||
SCWrite(self->pOwner, "", eFinish);
|
SCWrite(self->pOwner, "", eFinish);
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
devser.c
3
devser.c
@ -308,7 +308,8 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[])
|
|||||||
devser->steps = -1; /* no debugging by default */
|
devser->steps = -1; /* no debugging by default */
|
||||||
devser->status = AsconUnconnected;
|
devser->status = AsconUnconnected;
|
||||||
devser->startTime = -1;
|
devser->startTime = -1;
|
||||||
TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0);
|
TaskRegisterN(pServ->pTasker, AsconHostport(ascon),
|
||||||
|
DevQueueTask, NULL, NULL, devser, 0);
|
||||||
return devser;
|
return devser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ int RunDiffScan(pDiffScan self, pScanData pScan,
|
|||||||
InvokeCallBack(self->scanObject->pCall, SCANSTART, self->scanObject);
|
InvokeCallBack(self->scanObject->pCall, SCANSTART, self->scanObject);
|
||||||
|
|
||||||
|
|
||||||
lID = TaskRegister(pServ->pTasker, DiffScanTask, NULL, NULL, self, 10);
|
lID = TaskRegisterN(pServ->pTasker,"diffscan", DiffScanTask, NULL, NULL, self, 10);
|
||||||
TaskWait(pServ->pTasker, lID);
|
TaskWait(pServ->pTasker, lID);
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +113,8 @@ experiment.
|
|||||||
property on the node or as given on the command line. The alias is expected to match the size and type of
|
property on the node or as given on the command line. The alias is expected to match the size and type of
|
||||||
the data. Please note that hipadaba stores all floats as double which is NX_FLOAT64 as number type. Writing
|
the data. Please note that hipadaba stores all floats as double which is NX_FLOAT64 as number type. Writing
|
||||||
data is started with the offset specified from the start of the data. This is useful to split a histogram
|
data is started with the offset specified from the start of the data. This is useful to split a histogram
|
||||||
memory area into separate detectors or whatever.
|
memory area into separate detectors or whatever. The length of the amount of data to
|
||||||
|
copy is implied by the dimension of the SDS alias points to.
|
||||||
<dt>nxscript puthdbslab path start size
|
<dt>nxscript puthdbslab path start size
|
||||||
<dd>Put a hipdaba node as a slab. The node must have a property nxalias to determine where to write to.
|
<dd>Put a hipdaba node as a slab. The node must have a property nxalias to determine where to write to.
|
||||||
Start and size are Tcl lists which give the start point where to write and the size of the data
|
Start and size are Tcl lists which give the start point where to write and the size of the data
|
||||||
|
2
exeman.c
2
exeman.c
@ -1175,8 +1175,10 @@ static int printBuffer(pExeMan self, SConnection * pCon,
|
|||||||
}
|
}
|
||||||
while (fgets(pLine, 511, fd) != NULL) {
|
while (fgets(pLine, 511, fd) != NULL) {
|
||||||
DynStringConcat(filePath, pLine);
|
DynStringConcat(filePath, pLine);
|
||||||
|
if(strrchr(pLine,(int)'\n') == NULL){
|
||||||
DynStringConcatChar(filePath,'\n');
|
DynStringConcatChar(filePath,'\n');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
SCWrite(pCon, GetCharArray(filePath), eValue);
|
SCWrite(pCon, GetCharArray(filePath), eValue);
|
||||||
DeleteDynString(filePath);
|
DeleteDynString(filePath);
|
||||||
|
13
fomerge.c
13
fomerge.c
@ -19,6 +19,9 @@
|
|||||||
extended to support nxscripted file writing: Mark Koennecke, May 2004
|
extended to support nxscripted file writing: Mark Koennecke, May 2004
|
||||||
|
|
||||||
extended to support GTSE, Mark Koennecke, May 2008
|
extended to support GTSE, Mark Koennecke, May 2008
|
||||||
|
|
||||||
|
modifed to support second generation HM's via the bridge,
|
||||||
|
Mark Koennecke, December 2012
|
||||||
--------------------------------------------------------------------------*/
|
--------------------------------------------------------------------------*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -428,20 +431,20 @@ static int updateHMFMData(SicsInterp * pSics, SConnection * pCon)
|
|||||||
HistInt *data = NULL;
|
HistInt *data = NULL;
|
||||||
pHistMem pMem = NULL;
|
pHistMem pMem = NULL;
|
||||||
|
|
||||||
pMem = (pHistMem) FindCommandData(pSics, "hm2", "HistMem");
|
pMem = (pHistMem) FindHM(pSics, "hm2");
|
||||||
if (pMem == NULL) {
|
if (pMem == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fTimeBin = GetHistTimeBin(pMem, &iTime);
|
fTimeBin = GetHistTimeBin(pMem, &iTime);
|
||||||
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, MIDDLE);
|
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, MIDDLE);
|
||||||
|
|
||||||
pMem = (pHistMem) FindCommandData(pSics, "hm1", "HistMem");
|
pMem = (pHistMem) FindHM(pSics, "hm1");
|
||||||
if (pMem == NULL) {
|
if (pMem == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, LOWER);
|
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, LOWER);
|
||||||
|
|
||||||
pMem = (pHistMem) FindCommandData(pSics, "hm3", "HistMem");
|
pMem = (pHistMem) FindHM(pSics, "hm3");
|
||||||
if (pMem == NULL) {
|
if (pMem == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -567,7 +570,7 @@ static int TOFLambda(SicsInterp * pSics, SConnection * pCon,
|
|||||||
float fCenter, fFWHM, fStdDev, fVal;
|
float fCenter, fFWHM, fStdDev, fVal;
|
||||||
float fMon, fData, distMonoDet, distFermiDet, tdiff, lambda;
|
float fMon, fData, distMonoDet, distFermiDet, tdiff, lambda;
|
||||||
|
|
||||||
pMem = (pHistMem) FindCommandData(pSics, "hm1", "HistMem");
|
pMem = (pHistMem) FindHM(pSics, "hm1");
|
||||||
if (pMem == NULL) {
|
if (pMem == NULL) {
|
||||||
SCWrite(pCon,
|
SCWrite(pCon,
|
||||||
"ERROR: need lower detector bank for lambda calculation",
|
"ERROR: need lower detector bank for lambda calculation",
|
||||||
@ -650,7 +653,7 @@ static float calcElastic(SicsInterp * pSics, SConnection * pCon)
|
|||||||
pHistMem pMem = NULL;
|
pHistMem pMem = NULL;
|
||||||
float fCenter, fFWHM, fStdDev, fVal;
|
float fCenter, fFWHM, fStdDev, fVal;
|
||||||
|
|
||||||
pMem = (pHistMem) FindCommandData(pSics, "hm2", "HistMem");
|
pMem = (pHistMem) FindHM(pSics, "hm2");
|
||||||
if (pMem == NULL) {
|
if (pMem == NULL) {
|
||||||
SCWrite(pCon,
|
SCWrite(pCon,
|
||||||
"ERROR: need middle detector bank for elastic peak calculation",
|
"ERROR: need middle detector bank for elastic peak calculation",
|
||||||
|
@ -647,7 +647,7 @@ void z1FromNormalBeam(double lambda, double omega, double gamma,
|
|||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
double circlify(double val)
|
double circlify(double val)
|
||||||
{
|
{
|
||||||
while (val > 360.) {
|
while (val >= 359.8) {
|
||||||
val -= 360.;
|
val -= 360.;
|
||||||
}
|
}
|
||||||
while (val < 0.) {
|
while (val < 0.) {
|
||||||
|
6
frame.c
6
frame.c
@ -66,7 +66,7 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM,
|
|||||||
if (nFrame >= noTimeBins) {
|
if (nFrame >= noTimeBins) {
|
||||||
nFrame = noTimeBins - 1;
|
nFrame = noTimeBins - 1;
|
||||||
}
|
}
|
||||||
if (isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) {
|
if (!isSecondGen(pHM) && isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) {
|
||||||
/*
|
/*
|
||||||
read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h
|
read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h
|
||||||
Again: be friendly: fix out of range frames
|
Again: be friendly: fix out of range frames
|
||||||
@ -81,7 +81,7 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM,
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if(isSINQHTTP(pHM->pDriv) && noTimeBins > 2){
|
} else if(!isSecondGen(pHM) && isSINQHTTP(pHM->pDriv) && noTimeBins > 2){
|
||||||
if(sansflag){
|
if(sansflag){
|
||||||
snprintf(histCommand,132,"sample:0:%d:%d:%d", iDim[0]*iDim[1], nFrame, nFrame+1);
|
snprintf(histCommand,132,"sample:0:%d:%d:%d", iDim[0]*iDim[1], nFrame, nFrame+1);
|
||||||
} else {
|
} else {
|
||||||
@ -244,7 +244,7 @@ int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
eError);
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pHM = (pHistMem) FindCommandData(pSics, argv[2], "HistMem");
|
pHM = (pHistMem) FindHM(pSics, argv[2]);
|
||||||
if (pHM == NULL) {
|
if (pHM == NULL) {
|
||||||
SCWrite(pCon, "ERROR: Did not find histogram memory", eError);
|
SCWrite(pCon, "ERROR: Did not find histogram memory", eError);
|
||||||
return 0;
|
return 0;
|
||||||
|
37
hipadaba.c
37
hipadaba.c
@ -10,6 +10,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <math.h>
|
||||||
#include "hipadaba.h"
|
#include "hipadaba.h"
|
||||||
|
|
||||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||||
@ -483,8 +484,32 @@ static unsigned short fletcher16( char *data, size_t len)
|
|||||||
result = result << 8 | checkB;
|
result = result << 8 | checkB;
|
||||||
return result ;
|
return result ;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
#define MAXLEN 65536
|
#define MAXLEN 65536
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static unsigned short longfletcher16(char *data, size_t len)
|
||||||
|
{
|
||||||
|
char buffer[MAXLEN];
|
||||||
|
int i, j, div, count;
|
||||||
|
char *pPtr;
|
||||||
|
|
||||||
|
if(len < MAXLEN){
|
||||||
|
return fletcher16(data,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sum together to run the more complex checksum on
|
||||||
|
* more juicy data
|
||||||
|
*/
|
||||||
|
div = (int)trunc((float)len/(float)MAXLEN);
|
||||||
|
for(i = 0; i < MAXLEN; i++){
|
||||||
|
pPtr = data + div*i;
|
||||||
|
for(j = 0; j < div; j++){
|
||||||
|
buffer[i] += *(pPtr + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fletcher16(buffer,MAXLEN);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
unsigned short getHdbCheckSum(hdbValue *val)
|
unsigned short getHdbCheckSum(hdbValue *val)
|
||||||
{
|
{
|
||||||
char *data;
|
char *data;
|
||||||
@ -928,12 +953,22 @@ static int canCopy(hdbValue * source, hdbValue * target)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(target->dataType == HIPINTAR &&
|
||||||
|
(source->dataType == HIPINTAR || source->dataType == HIPINTVARAR)
|
||||||
|
&& target->arrayLength == source->arrayLength){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (target->dataType == HIPFLOATVARAR) {
|
if (target->dataType == HIPFLOATVARAR) {
|
||||||
if (source->dataType == HIPFLOATAR ||
|
if (source->dataType == HIPFLOATAR ||
|
||||||
source->dataType == HIPFLOATVARAR) {
|
source->dataType == HIPFLOATVARAR) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(target->dataType == HIPFLOATAR &&
|
||||||
|
(source->dataType == HIPFLOATAR || source->dataType == HIPFLOATVARAR)
|
||||||
|
&& target->arrayLength == source->arrayLength){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (source->dataType != target->dataType) {
|
if (source->dataType != target->dataType) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
47
histmem.c
47
histmem.c
@ -70,6 +70,7 @@
|
|||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "site.h"
|
#include "site.h"
|
||||||
|
#include "histmemsec.h"
|
||||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -84,6 +85,27 @@ extern pHistDriver CreateRegressHM(pStringDict pOpt);
|
|||||||
*/
|
*/
|
||||||
extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
|
extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
int isSecondGen(pHistMem self)
|
||||||
|
{
|
||||||
|
pDummy test = (pDummy)self;
|
||||||
|
if(strcmp(test->pDescriptor->name,"HistMemSec") == 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
pHistMem FindHM(SicsInterp *pSics, char *name)
|
||||||
|
{
|
||||||
|
pHistMem result = NULL;
|
||||||
|
|
||||||
|
result = (pHistMem)FindCommandData(pSics,name,"HistMem");
|
||||||
|
if(result == NULL){
|
||||||
|
result = (pHistMem)FindCommandData(pSics,name,"HistMemSec");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
static int HistHalt(void *pData)
|
static int HistHalt(void *pData)
|
||||||
{
|
{
|
||||||
pHistMem self = NULL;
|
pHistMem self = NULL;
|
||||||
@ -715,6 +737,12 @@ long GetHistMonitor(pHistMem self, int i, SConnection * pCon)
|
|||||||
void HistDirty(pHistMem self)
|
void HistDirty(pHistMem self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
|
if(isSecondGen(self)){
|
||||||
|
SecHistDirty(self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(self->pDriv != NULL){
|
if(self->pDriv != NULL){
|
||||||
updateHMData(self->pDriv->data);
|
updateHMData(self->pDriv->data);
|
||||||
}
|
}
|
||||||
@ -724,6 +752,11 @@ void HistDirty(pHistMem self)
|
|||||||
const float *GetHistTimeBin(pHistMem self, int *iLength)
|
const float *GetHistTimeBin(pHistMem self, int *iLength)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
|
if(isSecondGen(self)){
|
||||||
|
return GetSecHistTimeBin(self,iLength);
|
||||||
|
}
|
||||||
|
|
||||||
*iLength = getNoOfTimebins(self->pDriv->data);
|
*iLength = getNoOfTimebins(self->pDriv->data);
|
||||||
return getTimeBinning(self->pDriv->data);
|
return getTimeBinning(self->pDriv->data);
|
||||||
}
|
}
|
||||||
@ -733,6 +766,10 @@ int GetHistLength(pHistMem self)
|
|||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
|
if(isSecondGen(self)){
|
||||||
|
return GetSecHistLength(self);
|
||||||
|
}
|
||||||
|
|
||||||
return getHMDataLength(self->pDriv->data);
|
return getHMDataLength(self->pDriv->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,6 +864,11 @@ int GetHistogram(pHistMem self, SConnection * pCon,
|
|||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
|
if(isSecondGen(self)){
|
||||||
|
return GetSecHistogram(self,pCon,i,iStart,iEnd,lData,iDataLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!self->iInit) {
|
if (!self->iInit) {
|
||||||
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
|
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
|
||||||
return 0;
|
return 0;
|
||||||
@ -883,6 +925,11 @@ HistInt *GetHistogramPointer(pHistMem self, SConnection * pCon)
|
|||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
|
if(isSecondGen(self)){
|
||||||
|
return GetSecHistogramPointer(self,pCon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!self->iInit) {
|
if (!self->iInit) {
|
||||||
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
|
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
242
histmemsec.c
242
histmemsec.c
@ -10,10 +10,17 @@
|
|||||||
* copyright: see file COPYRIGHT
|
* copyright: see file COPYRIGHT
|
||||||
*
|
*
|
||||||
* Mark Koennecke, May 2009
|
* Mark Koennecke, May 2009
|
||||||
|
*
|
||||||
|
* Added bridging routines implementing first gen HM interfaces
|
||||||
|
*
|
||||||
|
* Mark Koennecke, December 2012
|
||||||
*/
|
*/
|
||||||
#include <sics.h>
|
#include <sics.h>
|
||||||
#include <sicshipadaba.h>
|
#include <sicshipadaba.h>
|
||||||
#include <counter.h>
|
#include <counter.h>
|
||||||
|
#include "HistMem.h"
|
||||||
|
#include "HistMem.i"
|
||||||
|
#include "arrayutil.h"
|
||||||
|
|
||||||
#define CONFIG 1005
|
#define CONFIG 1005
|
||||||
|
|
||||||
@ -82,6 +89,45 @@ static int ResetCmd(pSICSOBJ ccmd, SConnection * pCon,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int NoTimeBinCmd(pSICSOBJ ccmd, SConnection * pCon,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
pHdb timeNode = NULL;
|
||||||
|
|
||||||
|
timeNode = GetHipadabaNode(ccmd->objectNode,"time_binning");
|
||||||
|
if(timeNode == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: HM has no time binning",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCPrintf(pCon,eValue,"%s.totimebin = %d", ccmd->objectNode->name,
|
||||||
|
timeNode->value.arrayLength);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int TimebinsCmd(pSICSOBJ ccmd, SConnection * pCon,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
pHdb timeNode = NULL;
|
||||||
|
pDynString data= NULL;
|
||||||
|
|
||||||
|
timeNode = GetHipadabaNode(ccmd->objectNode,"time_binning");
|
||||||
|
if(timeNode == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: HM has no time binning",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data = formatValue(timeNode->value,timeNode);
|
||||||
|
if(data != NULL){
|
||||||
|
SCPrintf(pCon,eValue,"%s.timebins = %s", ccmd->objectNode->name,
|
||||||
|
GetCharArray(data));
|
||||||
|
DeleteDynString(data);
|
||||||
|
} else {
|
||||||
|
SCWrite(pCon,"ERROR: out of memory formatting timebins", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon,
|
static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon,
|
||||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
{
|
{
|
||||||
@ -124,6 +170,96 @@ static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int ConfigureCmd(pSICSOBJ ccmd, SConnection * pCon,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
pHdb dimNode = NULL;
|
||||||
|
|
||||||
|
if(nPar < 1) {
|
||||||
|
SCWrite(pCon,"ERROR: need a parameter to read", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dimNode = GetHipadabaNode(ccmd->objectNode,"dim");
|
||||||
|
|
||||||
|
assert(dimNode != NULL);
|
||||||
|
|
||||||
|
if(strcmp(par[0]->value.v.text,"dim0") == 0){
|
||||||
|
SCPrintf(pCon,eValue,"%s.dim0 = %d", ccmd->objectNode->name,
|
||||||
|
dimNode->value.v.intArray[0]);
|
||||||
|
} else if(strcmp(par[0]->value.v.text,"dim1") == 0){
|
||||||
|
SCPrintf(pCon,eValue,"%s.dim1 = %d", ccmd->objectNode->name,
|
||||||
|
dimNode->value.v.intArray[1]);
|
||||||
|
} else {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: subcommand %s to configure not found",
|
||||||
|
par[0]->value.v.text);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int SumCmd(pSICSOBJ ccmd, SConnection * pCon,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
pHdb dimNode = NULL, dataNode = NULL;
|
||||||
|
int xstart, xend, ystart, yend, i;
|
||||||
|
long lSum;
|
||||||
|
|
||||||
|
dimNode = GetHipadabaNode(ccmd->objectNode,"dim");
|
||||||
|
dataNode = GetHipadabaNode(ccmd->objectNode,"data");
|
||||||
|
assert(dimNode != NULL && dataNode != NULL);
|
||||||
|
|
||||||
|
switch(dimNode->value.arrayLength){
|
||||||
|
case 1:
|
||||||
|
if(nPar < 2) {
|
||||||
|
SCWrite(pCon,"ERROR: need start and end for summing 1D data",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
xstart = par[0]->value.v.intValue;
|
||||||
|
xend = par[1]->value.v.intValue;
|
||||||
|
if(xstart < 0){
|
||||||
|
xstart = 0;
|
||||||
|
}
|
||||||
|
if(xend > dataNode->value.arrayLength){
|
||||||
|
xend = dataNode->value.arrayLength;
|
||||||
|
}
|
||||||
|
for(i = xstart; i < xend; i++){
|
||||||
|
lSum += dataNode->value.v.intArray[i];
|
||||||
|
}
|
||||||
|
SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(nPar < 4) {
|
||||||
|
SCWrite(pCon,"ERROR: need start and end in x and y for summing 2D data",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
xstart = par[0]->value.v.intValue;
|
||||||
|
xend = par[1]->value.v.intValue;
|
||||||
|
if(xstart < 0){
|
||||||
|
xstart = 0;
|
||||||
|
}
|
||||||
|
if(xend > dimNode->value.v.intArray[0]){
|
||||||
|
xend = dimNode->value.v.intArray[0];
|
||||||
|
}
|
||||||
|
ystart = par[2]->value.v.intValue;
|
||||||
|
yend = par[3]->value.v.intValue;
|
||||||
|
if(ystart < 0){
|
||||||
|
ystart = 0;
|
||||||
|
}
|
||||||
|
if(yend > dimNode->value.v.intArray[1]){
|
||||||
|
yend = dimNode->value.v.intArray[1];
|
||||||
|
}
|
||||||
|
lSum = sumWindow(dataNode->value.v.intArray, xstart,xend,dimNode->value.v.intArray[0],
|
||||||
|
ystart, yend, dimNode->value.v.intArray[1]);
|
||||||
|
SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
|
||||||
|
default:
|
||||||
|
SCPrintf(pCon,eError, "ERROR: summing not supported for %s dimensional data",
|
||||||
|
dimNode->value.arrayLength);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
static int InitCmd(pSICSOBJ ccmd, SConnection * con,
|
static int InitCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
{
|
{
|
||||||
@ -228,6 +364,12 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
|
|
||||||
child = AddSICSHdbPar(node,"init", usMugger, MakeSICSFunc(InitCmd));
|
child = AddSICSHdbPar(node,"init", usMugger, MakeSICSFunc(InitCmd));
|
||||||
|
|
||||||
|
child = AddSICSHdbPar(node,"sum", usSpy, MakeSICSFunc(SumCmd));
|
||||||
|
AddSICSHdbPar(child, "xstart", usSpy, MakeHdbInt(0));
|
||||||
|
AddSICSHdbPar(child, "xend", usSpy, MakeHdbInt(0));
|
||||||
|
AddSICSHdbPar(child, "ystart", usSpy, MakeHdbInt(0));
|
||||||
|
AddSICSHdbPar(child, "yend", usSpy, MakeHdbInt(0));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* test TOF option
|
* test TOF option
|
||||||
*/
|
*/
|
||||||
@ -245,6 +387,10 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
AddSICSHdbPar(child, "start", usMugger, MakeHdbFloat(10.));
|
AddSICSHdbPar(child, "start", usMugger, MakeHdbFloat(10.));
|
||||||
AddSICSHdbPar(child, "step", usMugger, MakeHdbFloat(10.));
|
AddSICSHdbPar(child, "step", usMugger, MakeHdbFloat(10.));
|
||||||
AddSICSHdbPar(child, "np", usMugger, MakeHdbInt(10));
|
AddSICSHdbPar(child, "np", usMugger, MakeHdbInt(10));
|
||||||
|
|
||||||
|
child = AddSICSHdbPar(node,"notimebin", usSpy, MakeSICSFunc(NoTimeBinCmd));
|
||||||
|
child = AddSICSHdbPar(node,"timebins", usSpy, MakeSICSFunc(TimebinsCmd));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,3 +403,99 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*===========================================================================
|
||||||
|
This is a set of adapter functions which make the second gen HM look like
|
||||||
|
a first generation one. This saves me from rewriting all the calculation codes
|
||||||
|
based on the first gen HM
|
||||||
|
|
||||||
|
!!!! BEWARE: In the functions below pHistMem should never be a pointer to a
|
||||||
|
HistMem but rather a second generation HM which is a counter object !!!!
|
||||||
|
===============================================================================*/
|
||||||
|
const float *GetSecHistTimeBin(pHistMem self, int *iLength)
|
||||||
|
{
|
||||||
|
float *tb = NULL;
|
||||||
|
pHdb tbNode = NULL;
|
||||||
|
int i;
|
||||||
|
pCounter pCter;
|
||||||
|
|
||||||
|
assert(self->pDes->parNode != NULL);
|
||||||
|
|
||||||
|
pCter = (pCounter)self;
|
||||||
|
tbNode = GetHipadabaNode(self->pDes->parNode,"time_binning");
|
||||||
|
if(tbNode == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*iLength = tbNode->value.arrayLength;
|
||||||
|
if(*iLength != pCter->tbLength){
|
||||||
|
if(pCter->timeBinning){
|
||||||
|
free(pCter->timeBinning);
|
||||||
|
}
|
||||||
|
pCter->timeBinning = malloc(*iLength*sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < *iLength; i++){
|
||||||
|
pCter->timeBinning[i] = tbNode->value.v.floatArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (const float*)pCter->timeBinning;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
HistInt *GetSecHistogramPointer(pHistMem self,SConnection *pCon)
|
||||||
|
{
|
||||||
|
pHdb dataNode = NULL;
|
||||||
|
|
||||||
|
assert(self->pDes->parNode != NULL);
|
||||||
|
|
||||||
|
dataNode = GetHipadabaNode(self->pDes->parNode,"data");
|
||||||
|
if(dataNode == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (HistInt *)dataNode->value.v.intArray;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int GetSecHistogram(pHistMem self, SConnection *pCon,
|
||||||
|
int i,int iStart, int iEnd, HistInt *lData, int iDataLen)
|
||||||
|
{
|
||||||
|
pHdb dataNode = NULL;
|
||||||
|
|
||||||
|
assert(self->pDes->parNode != NULL);
|
||||||
|
|
||||||
|
dataNode = GetHipadabaNode(self->pDes->parNode,"data");
|
||||||
|
if(dataNode == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(iEnd > dataNode->value.arrayLength){
|
||||||
|
iEnd = dataNode->value.arrayLength;
|
||||||
|
}
|
||||||
|
if ((iEnd - iStart) > iDataLen / sizeof(HistInt)) {
|
||||||
|
SCWrite(pCon, "WARNING: truncating request to fit data space",
|
||||||
|
eWarning);
|
||||||
|
iEnd = (iDataLen / sizeof(HistInt)) - 1;
|
||||||
|
}
|
||||||
|
memcpy(lData,dataNode->value.v.intArray+iStart, (iEnd-iStart)*sizeof(int));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
void SecHistDirty(pHistMem self)
|
||||||
|
{
|
||||||
|
/* Nothing to do */
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int GetSecHistLength(pHistMem self)
|
||||||
|
{
|
||||||
|
pHdb dataNode = NULL;
|
||||||
|
int i, length = 1;
|
||||||
|
|
||||||
|
assert(self->pDes->parNode != NULL);
|
||||||
|
|
||||||
|
dataNode = GetHipadabaNode(self->pDes->parNode,"dim");
|
||||||
|
if(dataNode == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i < dataNode->value.arrayLength; i++){
|
||||||
|
length *= dataNode->value.v.intArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
@ -17,4 +17,12 @@
|
|||||||
int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
const float *GetSecHistTimeBin(pHistMem self, int *iLength);
|
||||||
|
HistInt *GetSecHistogramPointer(pHistMem self,SConnection *pCon);
|
||||||
|
int GetSecHistogram(pHistMem self, SConnection *pCon,
|
||||||
|
int i,int iStart, int iEnd, HistInt *lData, int iDataLen);
|
||||||
|
void SecHistDirty(pHistMem self);
|
||||||
|
int GetSecHistLength(pHistMem self);
|
||||||
|
|
||||||
|
|
||||||
#endif /*HISTMEMSEC_H_*/
|
#endif /*HISTMEMSEC_H_*/
|
||||||
|
@ -443,6 +443,9 @@ $\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int HistBlockCount(pHistMem self, SConnection *pCon);@\\
|
\mbox{}\verb@ int HistBlockCount(pHistMem self, SConnection *pCon);@\\
|
||||||
\mbox{}\verb@ void HistDirty(pHistMem self); @\\
|
\mbox{}\verb@ void HistDirty(pHistMem self); @\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ int isSecondGen(pHistMem self);@\\
|
||||||
|
\mbox{}\verb@ pHistMem FindHM(SicsInterp *pSics, char *name);@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@@$\Diamond$
|
\mbox{}\verb@@$\Diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
|
@ -347,6 +347,9 @@ controlled by the following functions:
|
|||||||
int HistBlockCount(pHistMem self, SConnection *pCon);
|
int HistBlockCount(pHistMem self, SConnection *pCon);
|
||||||
void HistDirty(pHistMem self);
|
void HistDirty(pHistMem self);
|
||||||
|
|
||||||
|
int isSecondGen(pHistMem self);
|
||||||
|
pHistMem FindHM(SicsInterp *pSics, char *name);
|
||||||
|
|
||||||
@}
|
@}
|
||||||
The first four functions are simple parameter enquiry and manipulation
|
The first four functions are simple parameter enquiry and manipulation
|
||||||
functions. GetHistMonitor returns the count on monitor number i for the
|
functions. GetHistMonitor returns the count on monitor number i for the
|
||||||
|
2
make_gen
2
make_gen
@ -42,7 +42,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
||||||
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
||||||
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
||||||
singlebinb.o
|
singlebinb.o taskobj.o sctcomtask.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o simdriv.o
|
MOTOROBJ = motor.o simdriv.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
10
nread.c
10
nread.c
@ -1090,6 +1090,7 @@ static int CommandAcceptCB(int handle, void *userData)
|
|||||||
{
|
{
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
pCommandCBData usData = NULL;
|
pCommandCBData usData = NULL;
|
||||||
|
char buffer[80];
|
||||||
|
|
||||||
pCon = SCreateConnection(pServ->pSics, handle, 3);
|
pCon = SCreateConnection(pServ->pSics, handle, 3);
|
||||||
usData = malloc(sizeof(CommandCBData));
|
usData = malloc(sizeof(CommandCBData));
|
||||||
@ -1104,7 +1105,9 @@ static int CommandAcceptCB(int handle, void *userData)
|
|||||||
}
|
}
|
||||||
usData->pCon = pCon;
|
usData->pCon = pCon;
|
||||||
usData->state = COLLECT;
|
usData->state = COLLECT;
|
||||||
TaskRegister(pServ->pTasker,
|
snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
|
||||||
|
TaskRegisterN(pServ->pTasker,
|
||||||
|
buffer,
|
||||||
SCTaskFunction,
|
SCTaskFunction,
|
||||||
SCSignalFunction, SCDeleteConnection, pCon, 1);
|
SCSignalFunction, SCDeleteConnection, pCon, 1);
|
||||||
ANETsetReadCallback(handle, CommandDataCB, usData, killCommandCBData);
|
ANETsetReadCallback(handle, CommandDataCB, usData, killCommandCBData);
|
||||||
@ -1293,6 +1296,7 @@ static int TelnetAcceptCB(int handle, void *userData)
|
|||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
pCommandCBData usData = NULL;
|
pCommandCBData usData = NULL;
|
||||||
pTelTask pTel = NULL;
|
pTelTask pTel = NULL;
|
||||||
|
char buffer[80];
|
||||||
|
|
||||||
pCon = SCreateConnection(pServ->pSics, handle, 3);
|
pCon = SCreateConnection(pServ->pSics, handle, 3);
|
||||||
usData = malloc(sizeof(CommandCBData));
|
usData = malloc(sizeof(CommandCBData));
|
||||||
@ -1316,7 +1320,9 @@ static int TelnetAcceptCB(int handle, void *userData)
|
|||||||
}
|
}
|
||||||
/* register connection and task */
|
/* register connection and task */
|
||||||
pCon->iTelnet = 1;
|
pCon->iTelnet = 1;
|
||||||
TaskRegister(pServ->pTasker,
|
snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
|
||||||
|
TaskRegisterN(pServ->pTasker,
|
||||||
|
buffer,
|
||||||
TelnetTask, TelnetSignal, DeleteTelnet, pTel, 1);
|
TelnetTask, TelnetSignal, DeleteTelnet, pTel, 1);
|
||||||
ANETsetReadCallback(handle, ANETTelnetProcess,
|
ANETsetReadCallback(handle, ANETTelnetProcess,
|
||||||
usData, killCommandCBData);
|
usData, killCommandCBData);
|
||||||
|
12
nserver.c
12
nserver.c
@ -179,7 +179,8 @@ int InitServer(char *file, pServer * pServ)
|
|||||||
assert((pReader =
|
assert((pReader =
|
||||||
CreateNetReader(self, iPasswordTimeOut,
|
CreateNetReader(self, iPasswordTimeOut,
|
||||||
iCommandTimeOut)) != NULL);
|
iCommandTimeOut)) != NULL);
|
||||||
TaskRegister(self->pTasker, NetReaderTask, NetReaderSignal, NULL, /* call DeleteNetReader later than TaskerDelete */
|
TaskRegisterN(self->pTasker, "Network Reader",
|
||||||
|
NetReaderTask, NetReaderSignal, NULL, /* call DeleteNetReader later than TaskerDelete */
|
||||||
pReader, 1);
|
pReader, 1);
|
||||||
self->pReader = pReader;
|
self->pReader = pReader;
|
||||||
|
|
||||||
@ -244,17 +245,18 @@ int InitServer(char *file, pServer * pServ)
|
|||||||
|
|
||||||
/* install environment monitor */
|
/* install environment monitor */
|
||||||
self->pMonitor = GetEnvMon(self->pSics);
|
self->pMonitor = GetEnvMon(self->pSics);
|
||||||
TaskRegister(self->pTasker,
|
TaskRegisterN(self->pTasker,"EV Monitor",
|
||||||
EnvMonTask, EnvMonSignal, NULL, self->pMonitor, 1);
|
EnvMonTask, EnvMonSignal, NULL, self->pMonitor, 1);
|
||||||
|
|
||||||
/* install performance monitor */
|
/* install performance monitor */
|
||||||
pMon = CreatePerfMon(20);
|
pMon = CreatePerfMon(20);
|
||||||
AddCommand(self->pSics, "Performance", PerfMonWrapper, DeletePerfMon,
|
AddCommand(self->pSics, "Performance", PerfMonWrapper, DeletePerfMon,
|
||||||
pMon);
|
pMon);
|
||||||
TaskRegister(self->pTasker, PerfMonTask, PerfMonSignal, NULL, pMon, 1);
|
TaskRegisterN(self->pTasker,"perfmon", PerfMonTask, PerfMonSignal, NULL, pMon, 1);
|
||||||
/* Install a second one for higher granularity measurement */
|
/* Install a second one for higher granularity measurement */
|
||||||
pMon = CreatePerfMon(2);
|
pMon = CreatePerfMon(2);
|
||||||
TaskRegister(self->pTasker, PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
|
TaskRegisterN(self->pTasker,"perfmon2",
|
||||||
|
PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
|
||||||
|
|
||||||
|
|
||||||
/* install telnet port */
|
/* install telnet port */
|
||||||
@ -469,7 +471,7 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
SetStatus(eUserWait);
|
SetStatus(eUserWait);
|
||||||
sWait.dFinish = DoubleTime() + (double)fVal;
|
sWait.dFinish = DoubleTime() + (double)fVal;
|
||||||
sWait.iEnd = 0;
|
sWait.iEnd = 0;
|
||||||
lID = TaskRegister(pTask, WaitTask, WaitSignal, NULL, &sWait, 1);
|
lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, 1);
|
||||||
TaskWait(pTask, lID);
|
TaskWait(pTask, lID);
|
||||||
SetStatus(eOld);
|
SetStatus(eOld);
|
||||||
if (SCGetInterrupt(pCon) != eContinue) {
|
if (SCGetInterrupt(pCon) != eContinue) {
|
||||||
|
2
nwatch.c
2
nwatch.c
@ -54,7 +54,7 @@ int NetWatchInit(void)
|
|||||||
return 0;
|
return 0;
|
||||||
memset(instance, 0, sizeof(NetWatch));
|
memset(instance, 0, sizeof(NetWatch));
|
||||||
instance->lMagic = NWMAGIC;
|
instance->lMagic = NWMAGIC;
|
||||||
TaskRegister(pServ->pTasker, NetWatchTask, NULL, NULL, NULL, 1);
|
TaskRegisterN(pServ->pTasker,"nwatch", NetWatchTask, NULL, NULL, NULL, 1);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ static int CountCallback(int iEvent, void *pEventData, void *pUser)
|
|||||||
self->nextUpdate = time(NULL) + self->updateIntervall;
|
self->nextUpdate = time(NULL) + self->updateIntervall;
|
||||||
self->iEnd = 0;
|
self->iEnd = 0;
|
||||||
self->pCon = pCon;
|
self->pCon = pCon;
|
||||||
TaskRegister(pServ->pTasker, UpdateTask, NULL, NULL, self, 1);
|
TaskRegisterN(pServ->pTasker, "NXupdater", UpdateTask, NULL, NULL, self, 1);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (iEvent == COUNTEND) {
|
} else if (iEvent == COUNTEND) {
|
||||||
self->iEnd = 1;
|
self->iEnd = 1;
|
||||||
|
1
ofac.c
1
ofac.c
@ -169,6 +169,7 @@ static void InitIniCommands(SicsInterp * pInter)
|
|||||||
SCMD("SicsAlias", SicsAlias);
|
SCMD("SicsAlias", SicsAlias);
|
||||||
SCMD("SicsUser", PWSicsUser);
|
SCMD("SicsUser", PWSicsUser);
|
||||||
SCMD("TokenInit", TokenInit);
|
SCMD("TokenInit", TokenInit);
|
||||||
|
SCMD("MakeTask", TaskOBJFactory);
|
||||||
SCMD("UpdateFactory", UpdateFactory);
|
SCMD("UpdateFactory", UpdateFactory);
|
||||||
SCMD("VarMake", VarFactory);
|
SCMD("VarMake", VarFactory);
|
||||||
SCMD("VelocitySelector", VelSelFactory);
|
SCMD("VelocitySelector", VelSelFactory);
|
||||||
|
@ -166,7 +166,8 @@ static int StartOscillation(pOscillator self, SConnection * pCon)
|
|||||||
/*
|
/*
|
||||||
start task
|
start task
|
||||||
*/
|
*/
|
||||||
self->taskID = TaskRegister(pServ->pTasker,
|
snprintf(pBueffel,sizeof(pBueffel),"Oscillate-%s", self->pMot->name);
|
||||||
|
self->taskID = TaskRegisterN(pServ->pTasker,pBueffel,
|
||||||
OscillationTask, NULL, NULL, self, 10);
|
OscillationTask, NULL, NULL, self, 10);
|
||||||
if (self->taskID < 0) {
|
if (self->taskID < 0) {
|
||||||
SCWrite(pCon, "ERROR: failed to start oscillation task", eError);
|
SCWrite(pCon, "ERROR: failed to start oscillation task", eError);
|
||||||
|
2
remob.c
2
remob.c
@ -953,7 +953,7 @@ static RemServer *RemServerInit(char *name, char *host, int port)
|
|||||||
remserver->taskActive = 1;
|
remserver->taskActive = 1;
|
||||||
remserver->interestActive = 0;
|
remserver->interestActive = 0;
|
||||||
remserver->forwardMessages = 1;
|
remserver->forwardMessages = 1;
|
||||||
TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill,
|
TaskRegisterN(pServ->pTasker,name, RemServerTask, NULL, RemServerKill,
|
||||||
remserver, 1);
|
remserver, 1);
|
||||||
return remserver;
|
return remserver;
|
||||||
}
|
}
|
||||||
|
9
sansbc.c
9
sansbc.c
@ -101,8 +101,7 @@ static int COGCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hm = FindCommandData(pServ->pSics,
|
hm = FindHM(pServ->pSics, par[0]->value.v.text);
|
||||||
par[0]->value.v.text, "HistMem");
|
|
||||||
if(hm == NULL){
|
if(hm == NULL){
|
||||||
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
|
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
|
||||||
return 0;
|
return 0;
|
||||||
@ -137,8 +136,7 @@ static int COCCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hm = FindCommandData(pServ->pSics,
|
hm = FindHM(pServ->pSics, par[0]->value.v.text);
|
||||||
par[0]->value.v.text, "HistMem");
|
|
||||||
if(hm == NULL){
|
if(hm == NULL){
|
||||||
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
|
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
|
||||||
return 0;
|
return 0;
|
||||||
@ -173,8 +171,7 @@ static int StatCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hm = FindCommandData(pServ->pSics,
|
hm = FindHM(pServ->pSics, par[0]->value.v.text);
|
||||||
par[0]->value.v.text, "HistMem");
|
|
||||||
if(hm == NULL){
|
if(hm == NULL){
|
||||||
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
|
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "syncedprot.h"
|
#include "syncedprot.h"
|
||||||
#include "scriptcontext.h"
|
#include "scriptcontext.h"
|
||||||
|
#include "sctcomtask.h"
|
||||||
|
|
||||||
typedef struct ContextItem {
|
typedef struct ContextItem {
|
||||||
struct ContextItem *next;
|
struct ContextItem *next;
|
||||||
@ -862,7 +863,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
|||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *ParText(Hdb * cmdNode, char *name,
|
char *ParText(Hdb * cmdNode, char *name,
|
||||||
int nPar, char *defaultValue)
|
int nPar, char *defaultValue)
|
||||||
{
|
{
|
||||||
Hdb *par;
|
Hdb *par;
|
||||||
@ -1412,15 +1413,6 @@ static char *TransactionHandler(void *actionData, char *lastReply,
|
|||||||
return st->command;
|
return st->command;
|
||||||
} else {
|
} else {
|
||||||
st->sent = 2;
|
st->sent = 2;
|
||||||
/*
|
|
||||||
if (st->controller->verbose) {
|
|
||||||
SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply);
|
|
||||||
}
|
|
||||||
if (st->controller->fd != NULL) {
|
|
||||||
fprintf(st->controller->fd,"%6.3f reply : %s\n", secondsOfMinute(), lastReply);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* printf("Transact: %s got %s\n", st->command, lastReply); */
|
|
||||||
if (lastReply == NULL) {
|
if (lastReply == NULL) {
|
||||||
lastReply = "";
|
lastReply = "";
|
||||||
}
|
}
|
||||||
@ -1487,12 +1479,6 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con,
|
|||||||
TransactionHandler, SctTransactMatch, NULL, NULL);
|
TransactionHandler, SctTransactMatch, NULL, NULL);
|
||||||
while (st->sent != 2) {
|
while (st->sent != 2) {
|
||||||
TaskYield(pServ->pTasker);
|
TaskYield(pServ->pTasker);
|
||||||
/* not yet tested:
|
|
||||||
if (SCGetInterrupt(con) != eContinue) {
|
|
||||||
DevUnschedule(c->devser, st, TransactionHandler, SctTransactMatch);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
if (st->reply != NULL) {
|
if (st->reply != NULL) {
|
||||||
SCWrite(con,st->reply,eValue);
|
SCWrite(con,st->reply,eValue);
|
||||||
@ -1722,7 +1708,7 @@ static void SctKillController(void *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pServ->pTasker) {
|
if (pServ->pTasker) {
|
||||||
TaskRegister(pServ->pTasker, SctDeferredTask, NULL, SctDeferredFree,
|
TaskRegisterN(pServ->pTasker,"killsct", SctDeferredTask, NULL, SctDeferredFree,
|
||||||
controller, 0);
|
controller, 0);
|
||||||
} else {
|
} else {
|
||||||
free(controller);
|
free(controller);
|
||||||
@ -1899,6 +1885,7 @@ void SctInit(void)
|
|||||||
sct->desc = CreateDescriptor("ScriptContext");
|
sct->desc = CreateDescriptor("ScriptContext");
|
||||||
AddCommand(pServ->pSics, "sct", SctCommand, SctKill, sct);
|
AddCommand(pServ->pSics, "sct", SctCommand, SctKill, sct);
|
||||||
AddCmd("makesctcontroller", SctMakeController);
|
AddCmd("makesctcontroller", SctMakeController);
|
||||||
|
AddCmd("makesctcomtask", SctMakeComTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SctVerbose(SctController * c)
|
int SctVerbose(SctController * c)
|
||||||
@ -1906,3 +1893,15 @@ int SctVerbose(SctController * c)
|
|||||||
return c->verbose;
|
return c->verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DevSer *SctGetDevser(void *data)
|
||||||
|
{
|
||||||
|
SctController *c;
|
||||||
|
|
||||||
|
pSICSOBJ ccmd = (pSICSOBJ)data;
|
||||||
|
assert(ccmd);
|
||||||
|
assert(strcmp(ccmd->pDes->name,"SctController") == 0);
|
||||||
|
|
||||||
|
|
||||||
|
c = (SctController *) ccmd->pPrivate;
|
||||||
|
return c->devser;
|
||||||
|
}
|
||||||
|
@ -35,5 +35,10 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node,
|
|||||||
* \return 1 for verbose, 0 for silent
|
* \return 1 for verbose, 0 for silent
|
||||||
*/
|
*/
|
||||||
int SctVerbose(SctController * c);
|
int SctVerbose(SctController * c);
|
||||||
|
/**
|
||||||
|
* retrieve the device serializer
|
||||||
|
* \param data A pointer to a SICSObject representing a SctController
|
||||||
|
* \param A pointer the the device serializer
|
||||||
|
*/
|
||||||
|
DevSer *SctGetDevser(void *data);
|
||||||
#endif
|
#endif
|
||||||
|
517
sctcomtask.c
Normal file
517
sctcomtask.c
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
/**
|
||||||
|
* This is another approach at using the scriptcontext system. It introduces
|
||||||
|
* the concept of a communication task which is executed against a device serializer,
|
||||||
|
* accessed via a given ScriptContext. Clients can:
|
||||||
|
* - Create CommTasks
|
||||||
|
* - Figure out their state
|
||||||
|
* - Retrieve reply data
|
||||||
|
* - wait for a ComTask to finish.
|
||||||
|
*
|
||||||
|
* The the purpose sctcomtask will keep a cache of pending and finished communications.
|
||||||
|
* Old runs will be deleted periodically. Nevertheless the cache can be listed in order
|
||||||
|
* to figure out what happened.
|
||||||
|
*
|
||||||
|
* The intended use is for C-code or scripts to interact in a serial manner with
|
||||||
|
* the asynchronous communication system implemented in devser and ascon. As a
|
||||||
|
* standalone implementation would share tons of code with scriptcontext, this has
|
||||||
|
* been implemented as an add on module to scriptcontext.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, December 2012
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include "sctcomtask.h"
|
||||||
|
#include "scriptcontext.h"
|
||||||
|
#include "sicsobj.h"
|
||||||
|
#include "sicsutil.h"
|
||||||
|
#include "sicshipadaba.h"
|
||||||
|
|
||||||
|
static unsigned int mamaID = 0L;
|
||||||
|
|
||||||
|
extern char *ParText(Hdb * cmdNode, char *name,
|
||||||
|
int nPar, char *defaultValue);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
typedef struct{
|
||||||
|
char *sendData;
|
||||||
|
char *replyData;
|
||||||
|
int replyDataLength;
|
||||||
|
int ID;
|
||||||
|
double startTime;
|
||||||
|
double endTime;
|
||||||
|
ComTaskState state;
|
||||||
|
}ComTask, *pComTask;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
struct ComTaskManager{
|
||||||
|
DevSer *devser;
|
||||||
|
unsigned int halfQueueLength;
|
||||||
|
ComTask *TaskQueue;
|
||||||
|
unsigned int iPtr;
|
||||||
|
};
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static void KillComTaskData(ComTask *queue, int length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < length; i++){
|
||||||
|
if(queue[i].sendData != NULL){
|
||||||
|
free(queue[i].sendData);
|
||||||
|
queue[i].sendData = NULL;
|
||||||
|
}
|
||||||
|
if(queue[i].replyData != NULL){
|
||||||
|
free(queue[i].replyData);
|
||||||
|
queue[i].replyData = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static char *ComTaskHandler(void *data, char *replyData, int commError)
|
||||||
|
{
|
||||||
|
pComTask task = (pComTask)data;
|
||||||
|
assert(task != NULL);
|
||||||
|
|
||||||
|
if(replyData == NULL){
|
||||||
|
task->state = eRunning;
|
||||||
|
return task->sendData;
|
||||||
|
} else {
|
||||||
|
if(task->replyData != NULL){
|
||||||
|
free(task->replyData);
|
||||||
|
}
|
||||||
|
task->replyData = strdup(replyData);
|
||||||
|
task->replyDataLength = strlen(replyData);
|
||||||
|
task->endTime = DoubleTime();
|
||||||
|
task->state = eFinished;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int ComTaskMatch(void *data1, void *data2)
|
||||||
|
{
|
||||||
|
pComTask task1 = (pComTask)data1;
|
||||||
|
pComTask task2 = (pComTask)data2;
|
||||||
|
|
||||||
|
assert(task1 && task2);
|
||||||
|
|
||||||
|
if(task1->ID == task2->ID){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
static char *stateName[] = {
|
||||||
|
"waiting",
|
||||||
|
"running",
|
||||||
|
"finished",
|
||||||
|
"unknown"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char* StateToText(ComTaskState state)
|
||||||
|
{
|
||||||
|
return stateName[(int)state];
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
static char* ComTaskInfo(void *data)
|
||||||
|
{
|
||||||
|
char *info = NULL;
|
||||||
|
char buf[] = {"NA"};
|
||||||
|
char *reply;
|
||||||
|
int length = 256;
|
||||||
|
|
||||||
|
pComTask task = (pComTask)data;
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if(task->sendData != NULL){
|
||||||
|
length += strlen(task->sendData);
|
||||||
|
}
|
||||||
|
if(task->replyData != NULL){
|
||||||
|
length += strlen(task->replyData);
|
||||||
|
}
|
||||||
|
info = calloc(length,sizeof(char));
|
||||||
|
if(info == NULL){
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
if(task->replyData == NULL){
|
||||||
|
reply = buf;
|
||||||
|
} else {
|
||||||
|
reply = task->replyData;
|
||||||
|
}
|
||||||
|
snprintf(info,length,"%s:%s:%lf:%s:%lf", StateToText(task->state),
|
||||||
|
task->sendData,task->startTime, reply, task->endTime);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
int StartComTask(ComTaskManager *manager, char *priority, char *sendData)
|
||||||
|
{
|
||||||
|
int ID, i;
|
||||||
|
unsigned int ptr;
|
||||||
|
DevPrio prio;
|
||||||
|
|
||||||
|
assert(manager != NULL && priority != NULL);
|
||||||
|
|
||||||
|
ID = mamaID;
|
||||||
|
mamaID++;
|
||||||
|
if(mamaID < 0){
|
||||||
|
mamaID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(manager->iPtr >= 2*manager->halfQueueLength){
|
||||||
|
KillComTaskData(manager->TaskQueue,manager->halfQueueLength);
|
||||||
|
memmove(manager->TaskQueue,&manager->TaskQueue[manager->halfQueueLength],
|
||||||
|
manager->halfQueueLength*sizeof(ComTask));
|
||||||
|
/**
|
||||||
|
* The pointers need to be cleared, not freed, in order to
|
||||||
|
* prevent double freeing when reusing them.
|
||||||
|
*/
|
||||||
|
for(i = manager->halfQueueLength; i < 2*manager->halfQueueLength; i++){
|
||||||
|
manager->TaskQueue[i].sendData = NULL;
|
||||||
|
manager->TaskQueue[i].replyData = NULL;
|
||||||
|
}
|
||||||
|
manager->iPtr = manager->halfQueueLength;
|
||||||
|
}
|
||||||
|
ptr = manager->iPtr;
|
||||||
|
manager->iPtr++;
|
||||||
|
|
||||||
|
manager->TaskQueue[ptr].ID = ID;
|
||||||
|
manager->TaskQueue[ptr].startTime = DoubleTime();
|
||||||
|
manager->TaskQueue[ptr].endTime = 0.;
|
||||||
|
manager->TaskQueue[ptr].state = eWaiting;
|
||||||
|
if(manager->TaskQueue[ptr].sendData != NULL){
|
||||||
|
free(manager->TaskQueue[ptr].sendData);
|
||||||
|
}
|
||||||
|
manager->TaskQueue[ptr].sendData = strdup(sendData);
|
||||||
|
if(manager->TaskQueue[ptr].replyData != NULL){
|
||||||
|
free(manager->TaskQueue[ptr].replyData);
|
||||||
|
}
|
||||||
|
manager->TaskQueue[ptr].replyData = NULL;
|
||||||
|
|
||||||
|
prio = DevText2Prio(priority);
|
||||||
|
DevQueue(manager->devser,
|
||||||
|
&manager->TaskQueue[ptr],
|
||||||
|
prio,
|
||||||
|
ComTaskHandler,
|
||||||
|
ComTaskMatch,
|
||||||
|
NULL,
|
||||||
|
ComTaskInfo);
|
||||||
|
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int StartComTaskCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
char *priority, *sendData;
|
||||||
|
int lID;
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
|
||||||
|
if(nPar < 2) {
|
||||||
|
SCWrite(con,"ERROR: need priorty and send data as parameters",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
priority = ParText(cmdNode,"priority",nPar,"read");
|
||||||
|
sendData = ParText(cmdNode,"send",nPar,"None");
|
||||||
|
|
||||||
|
manni = (ComTaskManager *)ccmd->pPrivate;
|
||||||
|
lID = StartComTask(manni, priority, sendData);
|
||||||
|
SCPrintf(con,eValue,"comtaskid = %ld", lID);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int ComTaskCompare(const void *data1, const void *data2)
|
||||||
|
{
|
||||||
|
pComTask task1 = (pComTask)data1;
|
||||||
|
pComTask task2 = (pComTask)data2;
|
||||||
|
|
||||||
|
assert(task1 && task2);
|
||||||
|
|
||||||
|
if(task1->ID < task2->ID){
|
||||||
|
return -1;
|
||||||
|
} else if(task1->ID > task2->ID){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
ComTaskState GetComTaskState(ComTaskManager *manager, int comTaskID)
|
||||||
|
{
|
||||||
|
ComTask key;
|
||||||
|
ComTask *task = NULL;
|
||||||
|
|
||||||
|
key.ID = comTaskID;
|
||||||
|
|
||||||
|
task = bsearch(&key,manager->TaskQueue,manager->iPtr,
|
||||||
|
sizeof(ComTask), ComTaskCompare);
|
||||||
|
if(task == NULL){
|
||||||
|
return eUnknown;
|
||||||
|
} else {
|
||||||
|
return task->state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int GetComTaskStateCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
int lID;
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
ComTaskState state;
|
||||||
|
|
||||||
|
if(nPar < 1) {
|
||||||
|
SCWrite(con,"ERROR: need task ID parameter",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lID = par[0]->value.v.intValue;
|
||||||
|
|
||||||
|
manni = (ComTaskManager *)ccmd->pPrivate;
|
||||||
|
state = GetComTaskState(manni,lID);
|
||||||
|
SCPrintf(con,eValue,"%d = %s", lID, StateToText(state));
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
const char *GetComTaskReply(ComTaskManager *manager,
|
||||||
|
int comTaskID, int *length)
|
||||||
|
{
|
||||||
|
ComTask key;
|
||||||
|
ComTask *task = NULL;
|
||||||
|
|
||||||
|
key.ID = comTaskID;
|
||||||
|
|
||||||
|
task = bsearch(&key,manager->TaskQueue,manager->iPtr,
|
||||||
|
sizeof(ComTask), ComTaskCompare);
|
||||||
|
if(task == NULL || task->state != eFinished){
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return (const char *)task->replyData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int GetComTaskReplyCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
int lID;
|
||||||
|
int length;
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
const char *reply;
|
||||||
|
|
||||||
|
if(nPar < 1) {
|
||||||
|
SCWrite(con,"ERROR: need task ID parameter",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lID = par[0]->value.v.intValue;
|
||||||
|
|
||||||
|
manni = (ComTaskManager *)ccmd->pPrivate;
|
||||||
|
reply = GetComTaskReply(manni,lID,&length);
|
||||||
|
if(reply == NULL){
|
||||||
|
SCPrintf(con,eError,"No reply for %ld found", lID);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
SCPrintf(con,eValue,"%d = %s", lID, reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------*/
|
||||||
|
void ComTaskWait(ComTaskManager *manager, int comTaskID)
|
||||||
|
{
|
||||||
|
|
||||||
|
ComTask key;
|
||||||
|
ComTask *task = NULL;
|
||||||
|
|
||||||
|
key.ID = comTaskID;
|
||||||
|
|
||||||
|
task = bsearch(&key,manager->TaskQueue,manager->iPtr,
|
||||||
|
sizeof(ComTask), ComTaskCompare);
|
||||||
|
if(task == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Hmmmmhhhh. It might be better to start a SICS task here and
|
||||||
|
* wait for it terminate. But this would essentially also call
|
||||||
|
* TaskYield or, worse, Taskwait.
|
||||||
|
*/
|
||||||
|
while(task->state != eFinished){
|
||||||
|
TaskYield(pServ->pTasker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int ComTaskWaitCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
int lID;
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
|
||||||
|
if(nPar < 1) {
|
||||||
|
SCWrite(con,"ERROR: need task ID parameter",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lID = par[0]->value.v.intValue;
|
||||||
|
|
||||||
|
manni = (ComTaskManager *)ccmd->pPrivate;
|
||||||
|
ComTaskWait(manni,lID);
|
||||||
|
SCWrite(con,"Done",eValue);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static int ComTaskListAllCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
pDynString list = NULL;
|
||||||
|
int i;
|
||||||
|
char *info;
|
||||||
|
|
||||||
|
manni = (ComTaskManager *)ccmd->pPrivate;
|
||||||
|
list = CreateDynString(256,256);
|
||||||
|
if(list == NULL){
|
||||||
|
SCWrite(con,"ERROR: out of memory listing ComTasks", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < manni->iPtr; i++){
|
||||||
|
info = ComTaskInfo((void *)&manni->TaskQueue[i]);
|
||||||
|
DynStringConcat(list,info);
|
||||||
|
DynStringConcatChar(list,'\n');
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
SCWrite(con,GetCharArray(list),eValue);
|
||||||
|
DeleteDynString(list);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
static int ComTaskListPendingCmd(pSICSOBJ ccmd, SConnection * con,
|
||||||
|
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||||
|
{
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
pDynString list = NULL;
|
||||||
|
int i;
|
||||||
|
char *info;
|
||||||
|
|
||||||
|
manni = (ComTaskManager *)ccmd->pPrivate;
|
||||||
|
list = CreateDynString(256,256);
|
||||||
|
if(list == NULL){
|
||||||
|
SCWrite(con,"ERROR: out of memory listing ComTasks", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < manni->iPtr; i++){
|
||||||
|
if(manni->TaskQueue[i].state != eFinished){
|
||||||
|
info = ComTaskInfo((void *)&manni->TaskQueue[i]);
|
||||||
|
DynStringConcat(list,info);
|
||||||
|
DynStringConcatChar(list,'\n');
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SCWrite(con,GetCharArray(list),eValue);
|
||||||
|
DeleteDynString(list);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static ComTaskManager *MakeComTaskManager(int length)
|
||||||
|
{
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
manni = calloc(1, sizeof(ComTaskManager));
|
||||||
|
if(manni != NULL){
|
||||||
|
manni->halfQueueLength=length;
|
||||||
|
manni->TaskQueue = calloc(length*2,sizeof(ComTask));
|
||||||
|
if(manni->TaskQueue == NULL){
|
||||||
|
free(manni);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return manni;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
static void KillComTaskManager(void *data)
|
||||||
|
{
|
||||||
|
ComTaskManager *manni = (ComTaskManager *)data;
|
||||||
|
|
||||||
|
if(manni == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(manni->TaskQueue != NULL){
|
||||||
|
free(manni->TaskQueue);
|
||||||
|
}
|
||||||
|
KillComTaskData(manni->TaskQueue,manni->halfQueueLength*2);
|
||||||
|
free(manni);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
int SctMakeComTask(SConnection * con, SicsInterp * sics,
|
||||||
|
void *object, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SICSOBJ *ccmd;
|
||||||
|
pHdb cmd = NULL;
|
||||||
|
ComTaskManager *manni = NULL;
|
||||||
|
int length = 64;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
SCWrite(con,"ERROR: need at least comtaskmanager name and sctcontroller as arguments",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccmd = (SICSOBJ *)FindCommandData(sics,argv[2],"SctController");
|
||||||
|
if(ccmd == NULL){
|
||||||
|
SCPrintf(con,eError,"ERROR: SctController %s not found",argv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argc > 3) {
|
||||||
|
length = atoi(argv[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
manni = MakeComTaskManager(length);
|
||||||
|
if(manni == NULL){
|
||||||
|
SCWrite(con,"ERROR: out of memory allocating ComTaskmanager",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
manni->devser = SctGetDevser(ccmd);
|
||||||
|
assert(manni->devser != NULL);
|
||||||
|
|
||||||
|
ccmd = MakeSICSOBJv(argv[1], "SctComTask", HIPNONE, usSpy);
|
||||||
|
assert(ccmd);
|
||||||
|
ccmd->pPrivate = manni;
|
||||||
|
ccmd->KillPrivate = KillComTaskManager;
|
||||||
|
|
||||||
|
AddCommand(pServ->pSics, argv[1], InterInvokeSICSOBJ, KillSICSOBJ, ccmd);
|
||||||
|
RegisterSICSOBJKillCmd(ccmd, argv[1]);
|
||||||
|
SetDescriptorKey(ccmd->pDes, "creationCommand", "0");
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||||
|
"start", usUser, MakeSICSFunc(StartComTaskCmd));
|
||||||
|
AddSICSHdbPar(cmd, "priority", usUser, MakeHdbText(""));
|
||||||
|
AddSICSHdbPar(cmd, "send", usUser, MakeHdbText("None"));
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||||
|
"state", usUser, MakeSICSFunc(GetComTaskStateCmd));
|
||||||
|
AddSICSHdbPar(cmd, "id", usUser, MakeHdbInt(0));
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||||
|
"reply", usUser, MakeSICSFunc(GetComTaskReplyCmd));
|
||||||
|
AddSICSHdbPar(cmd, "id", usUser, MakeHdbInt(0));
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||||
|
"wait", usUser, MakeSICSFunc(ComTaskWaitCmd));
|
||||||
|
AddSICSHdbPar(cmd, "id", usUser, MakeHdbInt(0));
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||||
|
"listall", usSpy, MakeSICSFunc(ComTaskListAllCmd));
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||||
|
"listpend", usSpy, MakeSICSFunc(ComTaskListPendingCmd));
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
78
sctcomtask.h
Normal file
78
sctcomtask.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* This is another approach at using the scriptcontext system. It introduces
|
||||||
|
* the concept of a communication task which is executed against a device serializer,
|
||||||
|
* accessed via a given ScriptContext. Clients can:
|
||||||
|
* - Create CommTasks
|
||||||
|
* - Figure out their state
|
||||||
|
* - Retrieve reply data
|
||||||
|
* - wait for a ComTask to finish.
|
||||||
|
*
|
||||||
|
* The the purpose sctcomtask will keep a cache of pending and finished communications.
|
||||||
|
* Old runs will be deleted periodically. Nevertheless the cache can be listed in order
|
||||||
|
* to figure out what happened.
|
||||||
|
*
|
||||||
|
* The intended use is for C-code or scripts to interact in a serial manner with
|
||||||
|
* the asynchronous communication system implemented in devser and ascon. As a
|
||||||
|
* standalone implementation would share tons of code with scriptcontext, this has
|
||||||
|
* been implemented as an add on module to scriptcontext.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, December 2012
|
||||||
|
*/
|
||||||
|
#ifndef __SCTCOMTASK
|
||||||
|
#define __SCTCOMTASK
|
||||||
|
#include <sics.h>
|
||||||
|
|
||||||
|
typedef struct ComTaskManager ComTaskManager;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
eWaiting,
|
||||||
|
eRunning,
|
||||||
|
eFinished,
|
||||||
|
eUnknown
|
||||||
|
} ComTaskState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard SIS installation function
|
||||||
|
*/
|
||||||
|
int SctMakeComTask(SConnection * con, SicsInterp * sics,
|
||||||
|
void *object, int argc, char *argv[]);
|
||||||
|
/*============================ client interface section ===========================*/
|
||||||
|
/**
|
||||||
|
* Start a communication task
|
||||||
|
* @param manager the communication task manager to start the communication with
|
||||||
|
* @param priority The priority of the task
|
||||||
|
* @param sendData The data to send to the device
|
||||||
|
* @return A positive com task ID on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int StartComTask(ComTaskManager *manager, char *priority, char *sendData);
|
||||||
|
/**
|
||||||
|
* Retrive the state of a communication task
|
||||||
|
* @param manager the communication task manager
|
||||||
|
* @param comTaskID The ID of the communication task to test
|
||||||
|
* @return The state of the task
|
||||||
|
*/
|
||||||
|
ComTaskState GetComTaskState(ComTaskManager *manager, int comTaskID);
|
||||||
|
/**
|
||||||
|
* Retrive the reply of a communication task
|
||||||
|
* @param manager the communication task manager
|
||||||
|
* @param comTaskID The ID of the communication task to test
|
||||||
|
* @param length An output parameter set to the length of the data returned
|
||||||
|
* @return NULL when this is called erroneously, the reply data else. The client is
|
||||||
|
* not supposed to delete the reply data. On the other hand, the client cannot rely
|
||||||
|
* on the data to be available for ever. Make a copy if long term storage of the reply
|
||||||
|
* data is necessary.
|
||||||
|
*/
|
||||||
|
const char *GetComTaskReply(ComTaskManager *manager, int comTaskID, int *length);
|
||||||
|
/**
|
||||||
|
* Wait for a communication task to finish
|
||||||
|
* @param manager the communication task manager
|
||||||
|
* @param comTaskID The ID of the communication task to test
|
||||||
|
* Please note that eventual timeouts are handled by devser and ascon.
|
||||||
|
*/
|
||||||
|
void ComTaskWait(ComTaskManager *manager, int comTaskID);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -166,7 +166,7 @@ static long SCTDRIVSetValue(void *data, SConnection * pCon, float val)
|
|||||||
OKOK or HWIdle when the motor finished driving
|
OKOK or HWIdle when the motor finished driving
|
||||||
HWFault when a hardware problem ocurred
|
HWFault when a hardware problem ocurred
|
||||||
HWPosFault when the hardware cannot reach a position
|
HWPosFault when the hardware cannot reach a position
|
||||||
Errors are duly to be printed to pCon
|
Errors are duely to be printed to pCon
|
||||||
For real motors CheckStatus again shall try hard to fix any
|
For real motors CheckStatus again shall try hard to fix any
|
||||||
issues with the motor
|
issues with the motor
|
||||||
------------------------------------------------------------------*/
|
------------------------------------------------------------------*/
|
||||||
|
@ -194,7 +194,7 @@ int SerialSicsExecute(void **pData, char *pCommand,
|
|||||||
control.data = CreateDynString(1024, 1024);
|
control.data = CreateDynString(1024, 1024);
|
||||||
|
|
||||||
/* start task */
|
/* start task */
|
||||||
lTask = TaskRegister(pServ->pTasker,
|
lTask = TaskRegisterN(pServ->pTasker,"serialwait",
|
||||||
SWTask, SWSignal, NULL, &control, 1);
|
SWTask, SWSignal, NULL, &control, 1);
|
||||||
/* wait for it to end */
|
/* wait for it to end */
|
||||||
TaskWait(pServ->pTasker, lTask);
|
TaskWait(pServ->pTasker, lTask);
|
||||||
|
@ -207,7 +207,7 @@ int MakeCron(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
}
|
}
|
||||||
pNew->stat = StatisticsNew(cmd);
|
pNew->stat = StatisticsNew(cmd);
|
||||||
|
|
||||||
TaskRegister(pServ->pTasker, CronTask, CronSignal, KillCron, pNew, 1);
|
TaskRegisterN(pServ->pTasker,"sicscron", CronTask, CronSignal, KillCron, pNew, 1);
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
13
sicsdata.c
13
sicsdata.c
@ -11,6 +11,8 @@
|
|||||||
Mark Koennecke, June 2003
|
Mark Koennecke, June 2003
|
||||||
|
|
||||||
added addto. Mark Koennecke, August 2009
|
added addto. Mark Koennecke, August 2009
|
||||||
|
|
||||||
|
Make Hipadaba compatible, Mark Koennecke, November 2012
|
||||||
----------------------------------------------------------------------*/
|
----------------------------------------------------------------------*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -47,7 +49,7 @@ static void KillSICSData(void *pData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
pSICSData createSICSData(void)
|
pSICSData createSICSData(char *name)
|
||||||
{
|
{
|
||||||
pSICSData pNew = NULL;
|
pSICSData pNew = NULL;
|
||||||
|
|
||||||
@ -63,6 +65,13 @@ pSICSData createSICSData(void)
|
|||||||
KillSICSData(pNew);
|
KillSICSData(pNew);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* pNew->pDes->parNode = MakeHipadabaNode(name,HIPINTVARAR, 1); */
|
||||||
|
/* if(pNew->pDes->parNode == NULL){ */
|
||||||
|
/* KillSICSData(pNew); */
|
||||||
|
/* return NULL; */
|
||||||
|
/* } */
|
||||||
|
/* pNew->pDes->parNode->value.doNotFree = 1; */
|
||||||
|
/* pNew->pDes->parNode->value.v.intArray = pNew->data; */
|
||||||
memset(pNew->data, 0, 1024 * sizeof(int));
|
memset(pNew->data, 0, 1024 * sizeof(int));
|
||||||
memset(pNew->dataType, 0, 1024 * sizeof(char));
|
memset(pNew->dataType, 0, 1024 * sizeof(char));
|
||||||
pNew->currentDataSize = 1024;
|
pNew->currentDataSize = 1024;
|
||||||
@ -1115,7 +1124,7 @@ int SICSDataFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
strtolower(argv[2]);
|
strtolower(argv[2]);
|
||||||
|
|
||||||
if (strcmp(argv[1], "new") == 0) {
|
if (strcmp(argv[1], "new") == 0) {
|
||||||
self = createSICSData();
|
self = createSICSData(argv[2]);
|
||||||
if (self == NULL) {
|
if (self == NULL) {
|
||||||
SCWrite(pCon, "ERROR: not enough memory to create SICSData", eError);
|
SCWrite(pCon, "ERROR: not enough memory to create SICSData", eError);
|
||||||
return 0;
|
return 0;
|
||||||
|
30
sicsdata.h
30
sicsdata.h
@ -15,34 +15,36 @@
|
|||||||
#define FLOATTYPE 1
|
#define FLOATTYPE 1
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
pObjectDescriptor pDes;
|
pObjectDescriptor pDes;
|
||||||
int *data;
|
int *data;
|
||||||
char *dataType;
|
char *dataType;
|
||||||
int dataUsed;
|
int dataUsed;
|
||||||
int currentDataSize;
|
int currentDataSize;
|
||||||
} SICSData, *pSICSData;
|
}SICSData, *pSICSData;
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
||||||
int *getSICSDataPointer(pSICSData self, int start, int end);
|
int *getSICSDataPointer(pSICSData self, int start, int end);
|
||||||
|
|
||||||
pSICSData createSICSData(void);
|
pSICSData createSICSData(char *name);
|
||||||
|
|
||||||
void assignSICSType(pSICSData self, int start, int end, int type);
|
void assignSICSType(pSICSData self, int start, int end, int type);
|
||||||
|
|
||||||
int SICSDataFactory(SConnection * pCon, SicsInterp * pSics,
|
int SICSDataFactory(SConnection *pCon, SicsInterp *pSics,
|
||||||
void *pData, int argc, char *argv[]);
|
void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
int SICSDataAction(SConnection * pCon, SicsInterp * pSics,
|
int SICSDataAction(SConnection *pCon, SicsInterp *pSics,
|
||||||
void *pData, int argc, char *argv[]);
|
void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
void clearSICSData(pSICSData self);
|
void clearSICSData(pSICSData self);
|
||||||
int getSICSDataInt(pSICSData self, int pos, int *value);
|
int getSICSDataInt(pSICSData self, int pos, int *value);
|
||||||
int getSICSDataFloat(pSICSData self, int pos, float *value);
|
int getSICSDataFloat(pSICSData self, int pos, float *value);
|
||||||
int setSICSDataInt(pSICSData self, int pos, int value);
|
int setSICSDataInt(pSICSData self, int pos, int value);
|
||||||
int setSICSDataFloat(pSICSData self, int pos, float value);
|
int setSICSDataFloat(pSICSData self, int pos, float value);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,7 +39,7 @@ This object exports the following functions:
|
|||||||
@d sidafunc @{
|
@d sidafunc @{
|
||||||
int *getSICSDataPointer(pSICSData self, int start, int end);
|
int *getSICSDataPointer(pSICSData self, int start, int end);
|
||||||
|
|
||||||
pSICSData createSICSData(void);
|
pSICSData createSICSData(char *name);
|
||||||
|
|
||||||
void assignSICSType(pSICSData self, int start, int end, int type);
|
void assignSICSType(pSICSData self, int start, int end, int type);
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ int SicsExit(SConnection * pCon, SicsInterp * pInterp, void *pData,
|
|||||||
|
|
||||||
if (SCMatchRights(pCon, usMugger)) { /* only Muggers are allowed to do it */
|
if (SCMatchRights(pCon, usMugger)) { /* only Muggers are allowed to do it */
|
||||||
SetInterrupt(eEndServer);
|
SetInterrupt(eEndServer);
|
||||||
lID = TaskRegister(pTask, WaitTask, NULL, NULL, NULL, 1);
|
lID = TaskRegisterN(pTask,"exittask", WaitTask, NULL, NULL, NULL, 1);
|
||||||
TaskWait(pTask, lID);
|
TaskWait(pTask, lID);
|
||||||
TaskStop(pTask);
|
TaskStop(pTask);
|
||||||
return 1;
|
return 1;
|
||||||
|
245
sicshipadaba.c
245
sicshipadaba.c
@ -36,6 +36,7 @@
|
|||||||
#include <macro.h>
|
#include <macro.h>
|
||||||
#include "commandlog.h"
|
#include "commandlog.h"
|
||||||
#include "arrayutil.h"
|
#include "arrayutil.h"
|
||||||
|
#include "HistMem.h"
|
||||||
|
|
||||||
#define MAX_HDB_PATH 1024
|
#define MAX_HDB_PATH 1024
|
||||||
|
|
||||||
@ -2503,6 +2504,50 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static int ZipReadHdbNode(SConnection * pCon, SicsInterp * pSics,
|
||||||
|
void *pData, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pHdb targetNode = NULL;
|
||||||
|
char error[512], oriPath[512];
|
||||||
|
int status;
|
||||||
|
pDynString parData = NULL, result= NULL;
|
||||||
|
Protocol protocol = normal_protocol;
|
||||||
|
OutCode outCode;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
SCWrite(pCon, "ERROR: need path to node", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(oriPath, argv[1], 511);
|
||||||
|
targetNode = FindHdbNode(NULL, argv[1], pCon);
|
||||||
|
if (targetNode == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(targetNode->value.dataType == HIPTEXT){
|
||||||
|
parData = formatValue(targetNode->value, targetNode);
|
||||||
|
if (parData == NULL) {
|
||||||
|
SCWrite(pCon, "ERROR: out of memory formatting data", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((protocol = isJSON(pCon)) == 1)
|
||||||
|
outCode = eHdbEvent;
|
||||||
|
else
|
||||||
|
outCode = eValue;
|
||||||
|
|
||||||
|
result = CreateDynString(128, 128);
|
||||||
|
formatNameValue(protocol, oriPath, GetCharArray(parData), result,
|
||||||
|
targetNode->value.dataType);
|
||||||
|
SCWrite(pCon, GetCharArray(result), outCode);
|
||||||
|
DeleteDynString(parData);
|
||||||
|
DeleteDynString(result);
|
||||||
|
} else {
|
||||||
|
status = sendZippedNodeData(targetNode, targetNode->value, pCon);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int GetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
|
static int GetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -2984,6 +3029,171 @@ static int isArrayNode(pHdb node)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int ArrayCopyNode(pHdb to, SConnection *pCon, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pHdb from = NULL;
|
||||||
|
int iStart, iLength;
|
||||||
|
hdbValue fromData;
|
||||||
|
|
||||||
|
from = FindHdbNode(NULL,argv[3],pCon);
|
||||||
|
if(from == NULL){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: source node %s not found", argv[3]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!isArrayNode(from)){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: %s is no array data node", argv[3]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart = 0;
|
||||||
|
iLength = from->value.arrayLength;
|
||||||
|
|
||||||
|
if(argc > 4) {
|
||||||
|
iStart = atoi(argv[4]);
|
||||||
|
if(iStart < 0) {
|
||||||
|
iStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(argc > 5) {
|
||||||
|
iLength = atoi(argv[5]);
|
||||||
|
if(iStart + iLength > from->value.arrayLength){
|
||||||
|
iLength = from->value.arrayLength - iStart - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(from->value.dataType){
|
||||||
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
|
fromData = MakeHdbIntArray(iLength, from->value.v.intArray+iStart);
|
||||||
|
break;
|
||||||
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
|
fromData = MakeHdbFloatArray(iLength, from->value.v.floatArray+iStart);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
/* cannot really happen */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!copyHdbValue(&fromData, &to->value)) {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot copy data from %s to %s because of data type mismatch",
|
||||||
|
argv[3],argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCSendOK(pCon);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int ArrayCopyOldHM(pHdb to, SConnection *pCon, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pHistMem hm = NULL;
|
||||||
|
int iStart, iLength;
|
||||||
|
int *data = NULL;
|
||||||
|
hdbValue copyData;
|
||||||
|
|
||||||
|
hm = (pHistMem)FindCommandData(pServ->pSics, argv[3],"HistMem");
|
||||||
|
if(hm == NULL){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot find HM %s", argv[3]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iStart = 0;
|
||||||
|
iLength = GetHistLength(hm);
|
||||||
|
|
||||||
|
if(argc > 4){
|
||||||
|
iStart = atoi(argv[4]);
|
||||||
|
iLength -= iStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argc > 5){
|
||||||
|
iLength = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iStart < 0){
|
||||||
|
iStart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iStart + iLength > GetHistLength(hm)){
|
||||||
|
iLength = GetHistLength(hm) - iStart - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = GetHistogramPointer(hm,pCon);
|
||||||
|
if(data == NULL){
|
||||||
|
SCPrintf(pCon,eError, "ERROR: failed to retrive HM data for %s", argv[3]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyData = MakeHdbIntArray(iLength, data + iStart);
|
||||||
|
if(!copyHdbValue(©Data, &to->value)) {
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot copy data from %s to %s because of data type mismatch",
|
||||||
|
argv[3],argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCSendOK(pCon);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int ArrayCopyOldTB(pHdb to, SConnection *pCon, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pHistMem hm = NULL;
|
||||||
|
int iStart, iLength, timeLength, i;
|
||||||
|
const float *data = NULL;
|
||||||
|
double *ddata = NULL;
|
||||||
|
hdbValue copyData;
|
||||||
|
|
||||||
|
hm = (pHistMem)FindCommandData(pServ->pSics, argv[3],"HistMem");
|
||||||
|
if(hm == NULL){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot find HM %s", argv[3]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iStart = 0;
|
||||||
|
data = GetHistTimeBin(hm,&timeLength);
|
||||||
|
if(data == NULL){
|
||||||
|
SCPrintf(pCon,eError, "ERROR: failed to retrive time binning for HM %s", argv[3]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iLength = timeLength;
|
||||||
|
|
||||||
|
if(argc > 4){
|
||||||
|
iStart = atoi(argv[4]);
|
||||||
|
iLength -= iStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argc > 5){
|
||||||
|
iLength = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iStart < 0){
|
||||||
|
iStart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iStart + iLength > timeLength){
|
||||||
|
iLength = timeLength - iStart - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddata = malloc(iLength*sizeof(double));
|
||||||
|
if(ddata == NULL){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: out of memory copying %s time binning to %s",
|
||||||
|
argv[3],argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i < iLength; i++){
|
||||||
|
ddata[i] = data[iStart+i];
|
||||||
|
}
|
||||||
|
copyData = MakeHdbFloatArray(iLength, ddata);
|
||||||
|
if(!copyHdbValue(©Data, &to->value)) {
|
||||||
|
SCPrintf(pCon,eError,
|
||||||
|
"ERROR: cannot copy data from %s to %s because of data type mismatch",
|
||||||
|
argv[3],argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
free(ddata);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
|
static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -3062,6 +3272,16 @@ static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strcmp(argv[2],"copynode") == 0){
|
||||||
|
return ArrayCopyNode(node, pCon, argc, argv);
|
||||||
|
}
|
||||||
|
if(strcmp(argv[2],"copyoldhm") == 0){
|
||||||
|
return ArrayCopyOldHM(node, pCon, argc, argv);
|
||||||
|
}
|
||||||
|
if(strcmp(argv[2],"copyoldtb") == 0){
|
||||||
|
return ArrayCopyOldTB(node, pCon, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
idx = atoi(argv[2]);
|
idx = atoi(argv[2]);
|
||||||
if(idx < 0 || idx >= node->value.arrayLength ){
|
if(idx < 0 || idx >= node->value.arrayLength ){
|
||||||
SCPrintf(pCon,eError,"ERROR: %d is out of range 0 - %d",
|
SCPrintf(pCon,eError,"ERROR: %d is out of range 0 - %d",
|
||||||
@ -3078,7 +3298,6 @@ static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
node->value.v.floatArray[idx] = atof(argv[3]);
|
node->value.v.floatArray[idx] = atof(argv[3]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
NotifyHipadabaPar(node, pCon);
|
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3408,6 +3627,27 @@ static int ListSICSHdbProperty(SConnection * pCon, SicsInterp * pSics,
|
|||||||
DeleteDynString(data);
|
DeleteDynString(data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int CallNotify(SConnection * pCon, SicsInterp * pSics,
|
||||||
|
void *pData, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pHdb node = NULL;
|
||||||
|
|
||||||
|
if(argc < 2) {
|
||||||
|
SCPrintf(pCon,eError, "ERROR: require path argument to %s", argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = GetHipadabaNode(GetHipadabaRoot(), argv[1]);
|
||||||
|
if(node == NULL){
|
||||||
|
SCPrintf(pCon,eError,"ERROR: cannot find node %s to notify", argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotifyHipadabaPar(node,pCon);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static pHdb matchHdbProp(pHdb root, char *propname, char *buffer)
|
static pHdb matchHdbProp(pHdb root, char *propname, char *buffer)
|
||||||
@ -3432,7 +3672,6 @@ static pHdb matchHdbProp(pHdb root, char *propname, char *buffer)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics,
|
static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics,
|
||||||
void *pData, int argc, char *argv[])
|
void *pData, int argc, char *argv[])
|
||||||
@ -3495,6 +3734,7 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics,
|
|||||||
AddCommand(pSics, "hget", GetHdbNode, NULL, NULL);
|
AddCommand(pSics, "hget", GetHdbNode, NULL, NULL);
|
||||||
AddCommand(pSics, "hval", GetHdbVal, NULL, NULL);
|
AddCommand(pSics, "hval", GetHdbVal, NULL, NULL);
|
||||||
AddCommand(pSics, "hzipget", ZipGetHdbNode, NULL, NULL);
|
AddCommand(pSics, "hzipget", ZipGetHdbNode, NULL, NULL);
|
||||||
|
AddCommand(pSics, "hzipread", ZipReadHdbNode, NULL, NULL);
|
||||||
AddCommand(pSics, "hlist", ListHdbNode, NULL, NULL);
|
AddCommand(pSics, "hlist", ListHdbNode, NULL, NULL);
|
||||||
AddCommand(pSics, "hnotify", AutoNotifyHdbNode, NULL, NULL);
|
AddCommand(pSics, "hnotify", AutoNotifyHdbNode, NULL, NULL);
|
||||||
AddCommand(pSics, "hdelcb", RemoveHdbCallback, NULL, NULL);
|
AddCommand(pSics, "hdelcb", RemoveHdbCallback, NULL, NULL);
|
||||||
@ -3508,6 +3748,7 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics,
|
|||||||
AddCommand(pSics, "hgetpropval", GetSICSHdbPropertyVal, NULL, NULL);
|
AddCommand(pSics, "hgetpropval", GetSICSHdbPropertyVal, NULL, NULL);
|
||||||
AddCommand(pSics, "hmatchprop", MatchHdbProperty, NULL, NULL);
|
AddCommand(pSics, "hmatchprop", MatchHdbProperty, NULL, NULL);
|
||||||
AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL);
|
AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL);
|
||||||
|
AddCommand(pSics, "hcallnotify",CallNotify, NULL, NULL);
|
||||||
|
|
||||||
InstallSICSPoll(pCon, pSics, pData, argc, argv);
|
InstallSICSPoll(pCon, pSics, pData, argc, argv);
|
||||||
poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll");
|
poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll");
|
||||||
|
84
sicsobj.c
84
sicsobj.c
@ -36,56 +36,6 @@ void DefaultFree(void *data)
|
|||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static void saveSICSNodeBroken(pHdb node, char *prefix, FILE * fd)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
nodes with the property __save are saved
|
|
||||||
special cases:
|
|
||||||
__save=update: a hupdate command is used instead of a set command
|
|
||||||
__save=kids: save kids, but not the value of this node
|
|
||||||
*/
|
|
||||||
char newprefix[1024], val[20];
|
|
||||||
char path[MAX_HDB_PATH];
|
|
||||||
pHdb child;
|
|
||||||
hdbValue v;
|
|
||||||
pDynString data = NULL;
|
|
||||||
char *cmd;
|
|
||||||
char *str, *value;
|
|
||||||
|
|
||||||
cmd = GetHdbProp(node, "creationCmd");
|
|
||||||
if (cmd != NULL) {
|
|
||||||
GetHdbPath(node, path, sizeof path);
|
|
||||||
fprintf(fd, cmd, prefix, path);
|
|
||||||
fprintf(fd, "\n");
|
|
||||||
}
|
|
||||||
if (GetHdbProperty(node, "__save", val, 20) == 1) {
|
|
||||||
if (strcasecmp(val, "kids") != 0) {
|
|
||||||
GetHipadabaPar(node, &v, NULL);
|
|
||||||
data = formatValue(v, node);
|
|
||||||
if (data != NULL) {
|
|
||||||
value = GetCharArray(data);
|
|
||||||
str = Arg2Tcl(1, &value, NULL, 0);
|
|
||||||
if (strcasecmp(val, "update") == 0) {
|
|
||||||
GetHdbPath(node, path, sizeof path);
|
|
||||||
fprintf(fd, "hupdate %s %s\n", path, str);
|
|
||||||
} else {
|
|
||||||
fprintf(fd, "%s %s\n", prefix, str);
|
|
||||||
}
|
|
||||||
DeleteDynString(data);
|
|
||||||
free(str);
|
|
||||||
}
|
|
||||||
ReleaseHdbValue(&v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
child = node->child;
|
|
||||||
while (child != NULL) {
|
|
||||||
snprintf(newprefix, 1024, "%s/%s", prefix, child->name);
|
|
||||||
saveSICSNodeBroken(child, newprefix, fd);
|
|
||||||
child = child->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
|
static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
|
||||||
{
|
{
|
||||||
@ -144,40 +94,6 @@ int SaveSICSOBJ(void *data, char *name, FILE * fd)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int SaveSICSOBJBroken(void *data, char *name, FILE * fd)
|
|
||||||
{
|
|
||||||
pSICSOBJ self = (pSICSOBJ) data;
|
|
||||||
char prefix[1024];
|
|
||||||
char path[MAX_HDB_PATH];
|
|
||||||
pHdb node;
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
if (self != NULL && self->objectNode != NULL) {
|
|
||||||
/*
|
|
||||||
node = self->objectNode->child;
|
|
||||||
cmd = GetHdbProp(self->objectNode, "creationCmd");
|
|
||||||
if (cmd != NULL) {
|
|
||||||
GetHdbPath(self->objectNode, path, sizeof path);
|
|
||||||
fprintf(fd, cmd, name, path);
|
|
||||||
fprintf(fd, "\n");
|
|
||||||
}
|
|
||||||
while (node != NULL) {
|
|
||||||
snprintf(prefix, 1024, "%s %s", name, node->name);
|
|
||||||
saveSICSNode(node, prefix, fd);
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
node = self->objectNode;
|
|
||||||
snprintf(prefix, 1024, "%s %s", name, node->name);
|
|
||||||
saveSICSNode(node, prefix, fd);
|
|
||||||
fprintf(fd, "\n");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void KillSICSOBJfromNode(void *userData)
|
static void KillSICSOBJfromNode(void *userData)
|
||||||
{
|
{
|
||||||
|
@ -379,7 +379,7 @@ int InstallSICSPoll(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
pNew->pCon = defCon;
|
pNew->pCon = defCon;
|
||||||
pNew->nPoll = 3;
|
pNew->nPoll = 3;
|
||||||
|
|
||||||
TaskRegister(pServ->pTasker, PollTask, SicsPollSignal, NULL, pNew, 10);
|
TaskRegisterN(pServ->pTasker,"sicspoll", PollTask, SicsPollSignal, NULL, pNew, 10);
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
AddCommand(pSics, argv[1], SICSPollWrapper, killSicsPoll, pNew);
|
AddCommand(pSics, argv[1], SICSPollWrapper, killSicsPoll, pNew);
|
||||||
|
@ -12,4 +12,5 @@
|
|||||||
#include "singlediff.h"
|
#include "singlediff.h"
|
||||||
|
|
||||||
void initializeSingleBisecting(pSingleDiff diff);
|
void initializeSingleBisecting(pSingleDiff diff);
|
||||||
|
void initializeSingleBisectingOrion(pSingleDiff diff);
|
||||||
#endif /*SINGELBI_H_ */
|
#endif /*SINGELBI_H_ */
|
||||||
|
100
singlebi.c
100
singlebi.c
@ -228,6 +228,46 @@ static int hklInRange(void *data, double fSet[4], int mask[4])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int hklInRangeOrion(void *data, double fSet[4], int mask[4])
|
||||||
|
{
|
||||||
|
pSingleDiff self = (pSingleDiff) data;
|
||||||
|
float fHard, fLimit;
|
||||||
|
char pError[132];
|
||||||
|
int i, test;
|
||||||
|
double dTheta;
|
||||||
|
pMotor pOmega, pChi, pPhi;
|
||||||
|
|
||||||
|
pOmega = SXGetMotor(Omega);
|
||||||
|
pChi = SXGetMotor(Chi);
|
||||||
|
pPhi = SXGetMotor(Phi);
|
||||||
|
if (pOmega == NULL || pChi == NULL || pPhi == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check two theta */
|
||||||
|
dTheta = fSet[0];
|
||||||
|
mask[0] = checkTheta(self, &dTheta);
|
||||||
|
fSet[0] = dTheta;
|
||||||
|
|
||||||
|
/* Orion is not upside down... */
|
||||||
|
fSet[2] = -1.*(fSet[2]+180.) + 360. ;
|
||||||
|
fSet[3] = circlify(fSet[3]+180.);
|
||||||
|
|
||||||
|
mask[1] = MotorCheckBoundary(pOmega, fSet[1], &fHard, pError, 131);
|
||||||
|
mask[2] = MotorCheckBoundary(pChi, fSet[2], &fHard, pError, 131);
|
||||||
|
mask[3] = MotorCheckBoundary(pPhi, fSet[3], &fHard, pError, 131);
|
||||||
|
for (i = 0, test = 0; i < 4; i++) {
|
||||||
|
test += mask[i];
|
||||||
|
}
|
||||||
|
if (test != 4) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
static int calculateBiSettings(pSingleDiff self,
|
static int calculateBiSettings(pSingleDiff self,
|
||||||
double *hkl, double *settings)
|
double *hkl, double *settings)
|
||||||
@ -282,6 +322,60 @@ static int calculateBiSettings(pSingleDiff self,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int calculateBiSettingsOrion(pSingleDiff self,
|
||||||
|
double *hkl, double *settings)
|
||||||
|
{
|
||||||
|
MATRIX z1;
|
||||||
|
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi, myPsi;
|
||||||
|
int i, test, mask[4], iRetry;
|
||||||
|
double lambda;
|
||||||
|
|
||||||
|
myPsi = hkl[3];
|
||||||
|
if (myPsi > 0.1) {
|
||||||
|
iRetry = 1;
|
||||||
|
} else {
|
||||||
|
iRetry = 699;
|
||||||
|
}
|
||||||
|
|
||||||
|
z1 = calculateScatteringVector(self, hkl);
|
||||||
|
|
||||||
|
/*
|
||||||
|
just the plain angle calculation
|
||||||
|
*/
|
||||||
|
if (!z1mToBisecting(self->lambda, z1, &stt, &om, &chi, &phi)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings[0] = stt;
|
||||||
|
settings[1] = om;
|
||||||
|
settings[2] = -1.*(180.+chi) + 360.;
|
||||||
|
settings[3] = phi+180.;
|
||||||
|
if (iRetry == 1) {
|
||||||
|
rotatePsi(om, chi, phi, myPsi, &ompsi, &chipsi, &phipsi);
|
||||||
|
settings[1] = ompsi;
|
||||||
|
settings[2] = circlify(chipsi);
|
||||||
|
settings[3] = circlify(phipsi);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
if (hklInRange(self, settings, mask) == 1) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
if (tryOmegaTweak(self, z1, &stt, &om, &chi, &phi) == 1) {
|
||||||
|
settings[0] = stt;
|
||||||
|
settings[1] = om;
|
||||||
|
settings[2] = chi;
|
||||||
|
settings[3] = phi;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return findAllowedBisecting(self->lambda, z1, settings, hklInRangeOrion,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
static int settingsToBiList(struct __SingleDiff *self, double *settings)
|
static int settingsToBiList(struct __SingleDiff *self, double *settings)
|
||||||
{
|
{
|
||||||
@ -471,3 +565,9 @@ void initializeSingleBisecting(pSingleDiff diff)
|
|||||||
diff->calcUBFromThree = calcBiUBFromThree;
|
diff->calcUBFromThree = calcBiUBFromThree;
|
||||||
diff->calcZ1 = calcBiZ1;
|
diff->calcZ1 = calcBiZ1;
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
void initializeSingleBisectingOrion(pSingleDiff diff)
|
||||||
|
{
|
||||||
|
initializeSingleBisecting(diff);
|
||||||
|
diff->calculateSettings = calculateBiSettingsOrion;
|
||||||
|
}
|
||||||
|
22
singlex.c
22
singlex.c
@ -227,6 +227,7 @@ static int findModeIndex(char *mode)
|
|||||||
"nb",
|
"nb",
|
||||||
"tas",
|
"tas",
|
||||||
"binb",
|
"binb",
|
||||||
|
"bio",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -254,6 +255,7 @@ static hdbCallbackReturn SetModeCB(pHdb node, void *userData,
|
|||||||
pTest = trim(set->v->v.text);
|
pTest = trim(set->v->v.text);
|
||||||
pCon = set->callData;
|
pCon = set->callData;
|
||||||
modeIdx = findModeIndex(pTest);
|
modeIdx = findModeIndex(pTest);
|
||||||
|
|
||||||
switch (modeIdx) {
|
switch (modeIdx) {
|
||||||
case Bisecting:
|
case Bisecting:
|
||||||
if (priv->chi == NULL || priv->om == NULL || priv->phi == NULL
|
if (priv->chi == NULL || priv->om == NULL || priv->phi == NULL
|
||||||
@ -269,6 +271,22 @@ static hdbCallbackReturn SetModeCB(pHdb node, void *userData,
|
|||||||
initializeSingleBisecting(priv->diffractometer);
|
initializeSingleBisecting(priv->diffractometer);
|
||||||
return hdbContinue;
|
return hdbContinue;
|
||||||
break;
|
break;
|
||||||
|
case BiO:
|
||||||
|
if (priv->chi == NULL || priv->om == NULL || priv->phi == NULL
|
||||||
|
|| priv->stt == NULL) {
|
||||||
|
if (pCon != NULL) {
|
||||||
|
SCWrite(pCon,
|
||||||
|
"ERROR: required motor for bisecting not configured",
|
||||||
|
eError);
|
||||||
|
}
|
||||||
|
return hdbAbort;
|
||||||
|
}
|
||||||
|
priv->mode = Bisecting;
|
||||||
|
initializeSingleBisectingOrion(priv->diffractometer);
|
||||||
|
free(set->v->v.text);
|
||||||
|
set->v->v.text = strdup("bi");
|
||||||
|
return hdbContinue;
|
||||||
|
break;
|
||||||
case NB:
|
case NB:
|
||||||
if (priv->nu == NULL || priv->om == NULL || priv->stt == NULL) {
|
if (priv->nu == NULL || priv->om == NULL || priv->stt == NULL) {
|
||||||
if (pCon != NULL) {
|
if (pCon != NULL) {
|
||||||
@ -874,7 +892,11 @@ pSICSOBJ SXGetReflectionList()
|
|||||||
SingleXModes SXGetMode()
|
SingleXModes SXGetMode()
|
||||||
{
|
{
|
||||||
pSingleX priv = (pSingleX) singlex->pPrivate;
|
pSingleX priv = (pSingleX) singlex->pPrivate;
|
||||||
|
if(priv->mode == BiO){
|
||||||
|
return Bisecting;
|
||||||
|
} else {
|
||||||
return priv->mode;
|
return priv->mode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -35,7 +35,7 @@ double SXGetLambda();
|
|||||||
pSICSOBJ SXGetReflectionList();
|
pSICSOBJ SXGetReflectionList();
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Bisecting, NB, Tas, BiNB,
|
Bisecting, NB, Tas, BiNB, BiO,
|
||||||
} SingleXModes;
|
} SingleXModes;
|
||||||
|
|
||||||
SingleXModes SXGetMode();
|
SingleXModes SXGetMode();
|
||||||
|
@ -297,5 +297,5 @@ void StatusFileDirty(void)
|
|||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void StatusFileInit(void)
|
void StatusFileInit(void)
|
||||||
{
|
{
|
||||||
TaskRegister(pServ->pTasker, StatusFileTask, NULL, NULL, NULL, 0);
|
TaskRegisterN(pServ->pTasker, "statusfile", StatusFileTask, NULL, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -723,11 +723,11 @@ static int calculateQMAndDrive(ptasMot self, SConnection * pCon)
|
|||||||
&angles);
|
&angles);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ENERGYTOBIG:
|
case ENERGYTOBIG:
|
||||||
SCWrite(pCon, "ERROR: desired energy to big", eError);
|
SCWrite(pCon, "ERROR: desired energy to big", eLogError);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
break;
|
break;
|
||||||
case TRIANGLENOTCLOSED:
|
case TRIANGLENOTCLOSED:
|
||||||
SCWrite(pCon, "ERROR: cannot close scattering triangle", eError);
|
SCWrite(pCon, "ERROR: cannot close scattering triangle", eLogError);
|
||||||
return HWFault;
|
return HWFault;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
216
task.c
216
task.c
@ -10,9 +10,15 @@
|
|||||||
|
|
||||||
NO WARRANTIES OF ANY KIND WHATSOEVER TAKEN BY ME OR MY EMPLOYER.
|
NO WARRANTIES OF ANY KIND WHATSOEVER TAKEN BY ME OR MY EMPLOYER.
|
||||||
YOU ARE AT YOUR OWN!
|
YOU ARE AT YOUR OWN!
|
||||||
|
|
||||||
|
Reworked to have a task name, stop by task name and better listing.
|
||||||
|
|
||||||
|
Mark Koennecke, December 2012
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#define READY 1
|
#define READY 1
|
||||||
@ -21,8 +27,11 @@
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
typedef struct __TaskHead {
|
typedef struct __TaskHead {
|
||||||
long lID;
|
long lID;
|
||||||
|
long groupID;
|
||||||
int iStatus;
|
int iStatus;
|
||||||
long lWait;
|
long lWait;
|
||||||
|
char *name;
|
||||||
|
time_t start_time;
|
||||||
TaskFunc pRun;
|
TaskFunc pRun;
|
||||||
SignalFunc pSignal;
|
SignalFunc pSignal;
|
||||||
void *pData;
|
void *pData;
|
||||||
@ -34,7 +43,7 @@ typedef struct __TaskHead {
|
|||||||
typedef struct __TaskMan {
|
typedef struct __TaskMan {
|
||||||
int iID;
|
int iID;
|
||||||
int iStop;
|
int iStop;
|
||||||
pTaskHead pCurrent;
|
pTaskHead pCurrent; /* Think trice before you interfere with this! */
|
||||||
pTaskHead pHead;
|
pTaskHead pHead;
|
||||||
} TaskMan;
|
} TaskMan;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -42,7 +51,7 @@ static long lIDMama = 0L;
|
|||||||
#define TASKERID 123399
|
#define TASKERID 123399
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
|
static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal,
|
||||||
void *pData, TaskKillFunc pKill)
|
void *pData, TaskKillFunc pKill)
|
||||||
{
|
{
|
||||||
pTaskHead pNew = NULL;
|
pTaskHead pNew = NULL;
|
||||||
@ -53,6 +62,8 @@ static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
|
|||||||
}
|
}
|
||||||
memset(pNew, 0, sizeof(TaskHead));
|
memset(pNew, 0, sizeof(TaskHead));
|
||||||
|
|
||||||
|
pNew->name = strdup(name);
|
||||||
|
pNew->start_time = time(NULL);
|
||||||
pNew->pRun = pTask;
|
pNew->pRun = pTask;
|
||||||
pNew->pSignal = pSignal;
|
pNew->pSignal = pSignal;
|
||||||
pNew->pData = pData;
|
pNew->pData = pData;
|
||||||
@ -60,6 +71,10 @@ static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
|
|||||||
pNew->lID = lIDMama++;
|
pNew->lID = lIDMama++;
|
||||||
pNew->iStatus = READY;
|
pNew->iStatus = READY;
|
||||||
|
|
||||||
|
if(lIDMama < 0){
|
||||||
|
lIDMama = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +88,9 @@ static void DeleteTaskHead(pTaskHead self)
|
|||||||
self->pKill(self->pData);
|
self->pKill(self->pData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(self->name != NULL){
|
||||||
|
free(self->name);
|
||||||
|
}
|
||||||
/* unlink */
|
/* unlink */
|
||||||
if (self->pPrevious != NULL) {
|
if (self->pPrevious != NULL) {
|
||||||
self->pPrevious->pNext = self->pNext;
|
self->pPrevious->pNext = self->pNext;
|
||||||
@ -105,7 +123,7 @@ int TaskerInit(pTaskMan * self)
|
|||||||
pNew->iID = TASKERID;
|
pNew->iID = TASKERID;
|
||||||
|
|
||||||
/* create a dummy task as start point */
|
/* create a dummy task as start point */
|
||||||
pDummyTask = MakeTaskHead(DummyTask, NULL, NULL, NULL);
|
pDummyTask = MakeTaskHead("init",DummyTask, NULL, NULL, NULL);
|
||||||
if (!pDummyTask) {
|
if (!pDummyTask) {
|
||||||
free(pNew);
|
free(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
@ -140,9 +158,14 @@ int TaskerDelete(pTaskMan * pData)
|
|||||||
*pData = NULL;
|
*pData = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*----------------------- temporary for backwards compatability -------------*/
|
||||||
|
long TaskRegister(pTaskMan self,TaskFunc pTask, SignalFunc pSignal,
|
||||||
|
TaskKillFunc pKill, void *pData, int iPriority)
|
||||||
|
{
|
||||||
|
return TaskRegisterN(self,"Unknown", pTask, pSignal, pKill, pData, iPriority);
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
long TaskRegister(pTaskMan self, TaskFunc pTask, SignalFunc pSignal,
|
long TaskRegisterN(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal,
|
||||||
TaskKillFunc pKill, void *pData, int iPriority)
|
TaskKillFunc pKill, void *pData, int iPriority)
|
||||||
{
|
{
|
||||||
pTaskHead pNew = NULL;
|
pTaskHead pNew = NULL;
|
||||||
@ -151,7 +174,7 @@ long TaskRegister(pTaskMan self, TaskFunc pTask, SignalFunc pSignal,
|
|||||||
assert(self->iID == TASKERID);
|
assert(self->iID == TASKERID);
|
||||||
assert(pTask);
|
assert(pTask);
|
||||||
|
|
||||||
pNew = MakeTaskHead(pTask, pSignal, pData, pKill);
|
pNew = MakeTaskHead(name, pTask, pSignal, pData, pKill);
|
||||||
if (!pNew) {
|
if (!pNew) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -166,7 +189,6 @@ long TaskRegister(pTaskMan self, TaskFunc pTask, SignalFunc pSignal,
|
|||||||
|
|
||||||
return pNew->lID;
|
return pNew->lID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static void IncrTaskPointer(pTaskMan self)
|
static void IncrTaskPointer(pTaskMan self)
|
||||||
{
|
{
|
||||||
@ -359,6 +381,10 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData)
|
|||||||
pCurrent = pNext;
|
pCurrent = pNext;
|
||||||
pNext = pCurrent->pNext;
|
pNext = pCurrent->pNext;
|
||||||
if (pCurrent->pRun == pTaskRun && pCurrent->pData == pData) {
|
if (pCurrent->pRun == pTaskRun && pCurrent->pData == pData) {
|
||||||
|
if(pCurrent == self->pCurrent){
|
||||||
|
/* cannot kill myself */
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* unlink */
|
/* unlink */
|
||||||
if (pCurrent->pPrevious != NULL) {
|
if (pCurrent->pPrevious != NULL) {
|
||||||
pCurrent->pPrevious->pNext = pCurrent->pNext;
|
pCurrent->pPrevious->pNext = pCurrent->pNext;
|
||||||
@ -366,8 +392,184 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData)
|
|||||||
if (pCurrent->pNext != NULL) {
|
if (pCurrent->pNext != NULL) {
|
||||||
pCurrent->pNext->pPrevious = pCurrent->pPrevious;
|
pCurrent->pNext->pPrevious = pCurrent->pPrevious;
|
||||||
}
|
}
|
||||||
|
if(pCurrent->name != NULL){
|
||||||
|
free(pCurrent->name);
|
||||||
|
}
|
||||||
free(pCurrent);
|
free(pCurrent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
int StopTask(pTaskMan self, char *name)
|
||||||
|
{
|
||||||
|
int iRet;
|
||||||
|
pTaskHead pCurrent, pNext;
|
||||||
|
|
||||||
|
if (self == NULL) return 0;
|
||||||
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
|
pNext = self->pHead->pNext; /* skip dummy task */
|
||||||
|
while (pNext != NULL) {
|
||||||
|
pCurrent = pNext;
|
||||||
|
pNext = pCurrent->pNext;
|
||||||
|
if (strcmp(pCurrent->name,name) == 0) {
|
||||||
|
if(self->pCurrent == pCurrent){
|
||||||
|
/**
|
||||||
|
* cannot kill myself
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* unlink */
|
||||||
|
if (pCurrent->pPrevious != NULL) {
|
||||||
|
pCurrent->pPrevious->pNext = pCurrent->pNext;
|
||||||
|
}
|
||||||
|
if (pCurrent->pNext != NULL) {
|
||||||
|
pCurrent->pNext->pPrevious = pCurrent->pPrevious;
|
||||||
|
}
|
||||||
|
if(pCurrent->name != NULL){
|
||||||
|
free(pCurrent->name);
|
||||||
|
}
|
||||||
|
free(pCurrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
int isTaskRunning(pTaskMan self, char *name)
|
||||||
|
{
|
||||||
|
int iRet;
|
||||||
|
pTaskHead pCurrent, pNext;
|
||||||
|
|
||||||
|
if (self == NULL) return 0;
|
||||||
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
|
pNext = self->pHead->pNext; /* skip dummy task */
|
||||||
|
while (pNext != NULL) {
|
||||||
|
pCurrent = pNext;
|
||||||
|
pNext = pCurrent->pNext;
|
||||||
|
if (strcmp(pCurrent->name,name) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
pTaskHead TaskIteratorStart(pTaskMan self)
|
||||||
|
{
|
||||||
|
if (self == NULL) return NULL;
|
||||||
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
|
return self->pHead->pNext; /* skip dummy task */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
pTaskHead TaskIteratorNext(pTaskHead it)
|
||||||
|
{
|
||||||
|
if(it != NULL){
|
||||||
|
return it->pNext;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
char *TaskDescription(pTaskHead it)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
int length;
|
||||||
|
const struct tm *tm;
|
||||||
|
|
||||||
|
if(it == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = strlen(it->name) + 120;
|
||||||
|
result = malloc(length*sizeof(char));
|
||||||
|
if(result == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(result,0,length*sizeof(char));
|
||||||
|
strcpy(result,it->name);
|
||||||
|
strcat(result,":");
|
||||||
|
|
||||||
|
length = strlen(result);
|
||||||
|
tm = localtime((const time_t *)&it->start_time);
|
||||||
|
strftime(result+length,100,"%F-%k-%m-%S",tm);
|
||||||
|
length = strlen(result);
|
||||||
|
snprintf(result+length,120-20,":%ld", it->lID);
|
||||||
|
length = strlen(result);
|
||||||
|
snprintf(result+length,120-40,":%ld", it->groupID);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------------*/
|
||||||
|
long GetTaskGroupID(pTaskMan self)
|
||||||
|
{
|
||||||
|
lIDMama++;
|
||||||
|
return lIDMama;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
void AddTaskToGroup(pTaskMan self, long taskID, long groupID)
|
||||||
|
{
|
||||||
|
pTaskHead pCurrent, pNext;
|
||||||
|
|
||||||
|
if (self == NULL) return;
|
||||||
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
|
pNext = self->pHead->pNext; /* skip dummy task */
|
||||||
|
while (pNext != NULL) {
|
||||||
|
pCurrent = pNext;
|
||||||
|
pNext = pCurrent->pNext;
|
||||||
|
if (pCurrent->lID == taskID) {
|
||||||
|
pCurrent->groupID = groupID;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------------
|
||||||
|
This simply checks if there are any more tasks with the desired groupID in the
|
||||||
|
list. If none, then all sub tasks have finished.
|
||||||
|
-----------------------------------------------------------------------------------*/
|
||||||
|
int isTaskGroupRunning(pTaskMan self, long groupID)
|
||||||
|
{
|
||||||
|
pTaskHead pCurrent, pNext;
|
||||||
|
|
||||||
|
if (self == NULL) return 0;
|
||||||
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
|
pNext = self->pHead->pNext; /* skip dummy task */
|
||||||
|
while (pNext != NULL) {
|
||||||
|
pCurrent = pNext;
|
||||||
|
pNext = pCurrent->pNext;
|
||||||
|
if (pCurrent->groupID == groupID) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------------*/
|
||||||
|
int TaskGroupTask(void *data)
|
||||||
|
{
|
||||||
|
pTaskGroupData self = (pTaskGroupData)data;
|
||||||
|
|
||||||
|
return isTaskGroupRunning(self->tasker,self->groupID);
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, long groupID)
|
||||||
|
{
|
||||||
|
pTaskHead pTemp, pEnd;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(self->iID == TASKERID);
|
||||||
|
|
||||||
|
/* Do one cycle until we are at the caller, then return to him */
|
||||||
|
pEnd = self->pCurrent;
|
||||||
|
IncrTaskPointer(self);
|
||||||
|
while (self->pCurrent != pEnd) {
|
||||||
|
if (self->pCurrent->pSignal && self->pCurrent->groupID == groupID) {
|
||||||
|
self->pCurrent->pSignal(self->pCurrent->pData, iSignal, pSigData);
|
||||||
|
}
|
||||||
|
IncrTaskPointer(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
92
task.h
92
task.h
@ -78,6 +78,23 @@ long TaskRegister(pTaskMan self, TaskFunc pTaskRun,
|
|||||||
On Success a positive value denoting the ID of the task is returned.
|
On Success a positive value denoting the ID of the task is returned.
|
||||||
On error a negative value is returned.
|
On error a negative value is returned.
|
||||||
*/
|
*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
long TaskRegisterN(pTaskMan self, char *name, TaskFunc pTaskRun,
|
||||||
|
SignalFunc pSignalFunc,
|
||||||
|
TaskKillFunc pKillFunc, void *pData, int iPriority);
|
||||||
|
/*
|
||||||
|
This call enter a new task into the system. The caller has to
|
||||||
|
specify:
|
||||||
|
a TaskFunction [Required]
|
||||||
|
a SignalFunction [Optional, can be NULL]
|
||||||
|
a KillFunction for task private data.
|
||||||
|
[Optional, can be NULL]
|
||||||
|
a pointer to task private data
|
||||||
|
[Optional, can be NULL]
|
||||||
|
a priority for this task. This is currently unused.
|
||||||
|
On Success a positive value denoting the ID of the task is returned.
|
||||||
|
On error a negative value is returned.
|
||||||
|
*/
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int TaskSchedule(pTaskMan self);
|
int TaskSchedule(pTaskMan self);
|
||||||
/*
|
/*
|
||||||
@ -117,5 +134,80 @@ int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
|
|||||||
/*
|
/*
|
||||||
remove the task with the given task function and the given data pointer
|
remove the task with the given task function and the given data pointer
|
||||||
*/
|
*/
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int StopTask(pTaskMan self, char *name);
|
||||||
|
/*
|
||||||
|
stop the task with the given name. Returns 0 on failure, 1 on success
|
||||||
|
*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int isTaskRunning(pTaskMan self, char *name);
|
||||||
|
/*
|
||||||
|
returns 1 when task name is running, 0 else
|
||||||
|
*/
|
||||||
|
/*===========================================================================
|
||||||
|
Iterating the task list. This works like:
|
||||||
|
|
||||||
|
pTaskHead it;
|
||||||
|
char *des;
|
||||||
|
|
||||||
|
for(it = TaskIteratorStart(self); it != NULL; it = TaskIteratorNext(it)){
|
||||||
|
des = TaskDescription(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
There are two limitations of the implementation here:
|
||||||
|
|
||||||
|
- Never, ever delete the Iterator it
|
||||||
|
- Do your iteration in one go or abandon it mid iteration. If another task
|
||||||
|
gets in between and registers new tasks or removes one, then the whole
|
||||||
|
iterator may be messed up.
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
pTaskHead TaskIteratorStart(pTaskMan self);
|
||||||
|
/*
|
||||||
|
starts iterating on the TaskList. Do NOT delete the returned pointer!
|
||||||
|
*/
|
||||||
|
pTaskHead TaskIteratorNext(pTaskHead it);
|
||||||
|
/*
|
||||||
|
Steps to the next element in the task list. Returns NULL when node.
|
||||||
|
Do NOT delete the returned pointer!
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *TaskDescription(pTaskHead it);
|
||||||
|
/*
|
||||||
|
get a description of the task at the current iterator
|
||||||
|
You are responsible for deleting the returned character array.
|
||||||
|
*/
|
||||||
|
/*=============================================================================
|
||||||
|
Task Groups. The implementation has the limit that any given task can
|
||||||
|
only be member of one task group
|
||||||
|
===============================================================================*/
|
||||||
|
long GetTaskGroupID(pTaskMan self);
|
||||||
|
/*
|
||||||
|
get the ID for a task group
|
||||||
|
*/
|
||||||
|
void AddTaskToGroup(pTaskMan self, long taskID, long groupID);
|
||||||
|
/*
|
||||||
|
Add taskID to the task group groupID
|
||||||
|
*/
|
||||||
|
int isTaskGroupRunning(pTaskMan self, long groupID);
|
||||||
|
/*
|
||||||
|
Returns 1 when the task group is still running, 0 else
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
pTaskMan tasker;
|
||||||
|
long groupID;
|
||||||
|
} TaskGroupData, *pTaskGroupData;
|
||||||
|
|
||||||
|
int TaskGroupTask(void *data);
|
||||||
|
/*
|
||||||
|
This is a task function which implements the common task of waiting
|
||||||
|
for a group of tasks to finish. It expects as data a TaskGroupData
|
||||||
|
structure.
|
||||||
|
*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, long groupID);
|
||||||
|
/*
|
||||||
|
signal only tasks in the group groupID
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
185
taskobj.c
Normal file
185
taskobj.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* This is the SICS interface object to the tasker module
|
||||||
|
*
|
||||||
|
* copyright: GPL
|
||||||
|
*
|
||||||
|
* Mark Koennecke, December 2012
|
||||||
|
*/
|
||||||
|
#include <sics.h>
|
||||||
|
#include "sicsobj.h"
|
||||||
|
#include "sicshipadaba.h"
|
||||||
|
#include "stptok.h"
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *scriptName;
|
||||||
|
SConnection *con;
|
||||||
|
} TclFunc, *pTclFunc;
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||||
|
pHdb par[], int nPar)
|
||||||
|
{
|
||||||
|
pDynString result = NULL;
|
||||||
|
char buffer[256], *pDes, *pPtr, name[80], time[80],id[80];
|
||||||
|
pTaskHead it = NULL;
|
||||||
|
|
||||||
|
result = CreateDynString(128,128);
|
||||||
|
if(result == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory in ListCmd", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
|
||||||
|
"Task", "Start_Time", "ID");
|
||||||
|
DynStringConcat(result,buffer);
|
||||||
|
DynStringConcatChar(result,'\n');
|
||||||
|
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||||
|
pDes = TaskDescription(it);
|
||||||
|
if(pDes != NULL){
|
||||||
|
pPtr = stptok(pDes,name,sizeof(name),":");
|
||||||
|
pPtr = stptok(pPtr,time,sizeof(name),":");
|
||||||
|
pPtr = stptok(pPtr,id,sizeof(name),":");
|
||||||
|
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
|
||||||
|
name,time,id);
|
||||||
|
DynStringConcat(result,buffer);
|
||||||
|
DynStringConcatChar(result,'\n');
|
||||||
|
free(pDes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SCWrite(pCon,GetCharArray(result),eValue);
|
||||||
|
DeleteDynString(result);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||||
|
pHdb par[], int nPar)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(nPar < 1){
|
||||||
|
SCWrite(pCon,"ERROR: need name of task to stop", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StopTask(pServ->pTasker,par[0]->value.v.text);
|
||||||
|
if(status == 0) {
|
||||||
|
SCWrite(pCon,"ERROR: cannot commit suicide!", eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
static int TclTaskFunction(void *pData)
|
||||||
|
{
|
||||||
|
int retVal, status ;
|
||||||
|
Tcl_Interp *pTcl;
|
||||||
|
|
||||||
|
pTclFunc self = (pTclFunc)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
pTcl = InterpGetTcl(pServ->pSics);
|
||||||
|
assert(pTcl != NULL);
|
||||||
|
|
||||||
|
MacroPush(self->con);
|
||||||
|
status = Tcl_Eval(pTcl, self->scriptName);
|
||||||
|
MacroPop();
|
||||||
|
traceSys("task","Executed %s with results %d and %s",self->scriptName, status,
|
||||||
|
Tcl_GetStringResult(pTcl));
|
||||||
|
if(status == 0){
|
||||||
|
retVal = atoi(Tcl_GetStringResult(pTcl));
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
static void KillTclFunc(void *pData)
|
||||||
|
{
|
||||||
|
pTclFunc self = (pTclFunc)pData;
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(self->scriptName){
|
||||||
|
free(self->scriptName);
|
||||||
|
}
|
||||||
|
if(self->con) {
|
||||||
|
SCDeleteConnection(self->con);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
static void TclFuncSignal(void *pData, int iSignal, void *pSigData)
|
||||||
|
{
|
||||||
|
int *iInt;
|
||||||
|
pTclFunc self = NULL;
|
||||||
|
|
||||||
|
self = (pTclFunc) pData;
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
if (iSignal == SICSINT) {
|
||||||
|
iInt = (int *) pSigData;
|
||||||
|
SCSetInterrupt(self->con,*iInt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int RunCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||||
|
pHdb par[], int nPar)
|
||||||
|
{
|
||||||
|
pTclFunc data = NULL;
|
||||||
|
|
||||||
|
if(nPar < 1) {
|
||||||
|
SCWrite(pCon,"ERROR: need the name of a script to run",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = malloc(sizeof(TclFunc));
|
||||||
|
if(data == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory in RunCmd",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(data,0,sizeof(TclFunc));
|
||||||
|
data->con = SCCreateDummyConnection(pServ->pSics);
|
||||||
|
data->scriptName = strdup(par[0]->value.v.text);
|
||||||
|
TaskRegisterN(pServ->pTasker,
|
||||||
|
data->scriptName,
|
||||||
|
TclTaskFunction,
|
||||||
|
TclFuncSignal,
|
||||||
|
KillTclFunc,
|
||||||
|
data, 0);
|
||||||
|
traceSys("task","Started task %s",data->scriptName);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pSICSOBJ pNew = NULL;
|
||||||
|
pHdb cmd = NULL, node;
|
||||||
|
|
||||||
|
pNew = SetupSICSOBJ(pCon,pSics,pData,argc,argv);
|
||||||
|
if(pNew == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy,
|
||||||
|
MakeSICSFunc(ListCmd));
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy,
|
||||||
|
MakeSICSFunc(KillCmd));
|
||||||
|
SetHdbProperty(cmd,"type","command");
|
||||||
|
SetHdbProperty(cmd,"priv","spy");
|
||||||
|
node = MakeSICSHdbPar("task",usSpy,MakeHdbText("banana"));
|
||||||
|
AddHipadabaChild(cmd,node,NULL);
|
||||||
|
|
||||||
|
cmd = AddSICSHdbPar(pNew->objectNode, "run", usSpy,
|
||||||
|
MakeSICSFunc(RunCmd));
|
||||||
|
SetHdbProperty(cmd,"type","command");
|
||||||
|
SetHdbProperty(cmd,"priv","spy");
|
||||||
|
node = MakeSICSHdbPar("script",usSpy,MakeHdbText("banana"));
|
||||||
|
AddHipadabaChild(cmd,node,NULL);
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
13
taskobj.h
Normal file
13
taskobj.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* This is the SICS interface object to the tasker module
|
||||||
|
*
|
||||||
|
* copyright: GPL
|
||||||
|
*
|
||||||
|
* Mark Koennecke, December 2012
|
||||||
|
*/
|
||||||
|
#ifndef TASKOBJ_
|
||||||
|
#define TASOBJ_
|
||||||
|
int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
#endif /*TASKOBJ_*/
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
exe batchpath ./
|
exe batchpath ./
|
||||||
exe syspath ./
|
exe syspath ./
|
||||||
|
|
||||||
@ -212,27 +211,22 @@ tasub outofplane 1
|
|||||||
tasub const ki
|
tasub const ki
|
||||||
tasub ss 1
|
tasub ss 1
|
||||||
tasub setub 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000
|
tasub setub 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000
|
||||||
tasub setnormal 0.000000 0.000000 0.000000
|
tasub setnormal 0.000000 0.000000 1.000000
|
||||||
tasub settarget 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
|
tasub settarget 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
|
||||||
tasub r1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
tasub r1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||||
tasub r2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
tasub r2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||||
tasub update
|
tasub update
|
||||||
#----- MultiMotor sa
|
#----- MultiMotor sa
|
||||||
sa recovernampos noeff a3 24 a4 48
|
sa recovernampos noeff a3 24 a4 48
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ref anglesheader stt,om,chi,phi
|
ref anglesheader stt,om,chi,phi
|
||||||
ref clear
|
ref clear
|
||||||
singlex cell { 0 0 0 0 0 0}
|
singlex cell 0 0 0 0 0 0
|
||||||
singlex oldub { 0 0 0 0 0 0 0 0 0}
|
singlex oldub 0 0 0 0 0 0 0 0 0
|
||||||
singlex ub { 0 0 0 0 0 0 0 0 0}
|
singlex ub 0 0 0 0 0 0 0 0 0
|
||||||
singlex planenormal { 0 0 0}
|
singlex planenormal 0 0 0
|
||||||
singlex mode bi
|
singlex mode bi
|
||||||
singlex spacegroup P
|
singlex spacegroup P
|
||||||
singlex peaksearch {}
|
singlex peaksearch
|
||||||
singlex peaksearch/min2t 5
|
singlex peaksearch/min2t 5
|
||||||
singlex peaksearch/step2t 1
|
singlex peaksearch/step2t 1
|
||||||
singlex peaksearch/max2t 15
|
singlex peaksearch/max2t 15
|
||||||
@ -244,7 +238,6 @@ singlex peaksearch/phimin 0
|
|||||||
singlex peaksearch/phimax 180
|
singlex peaksearch/phimax 180
|
||||||
singlex peaksearch/chimin 90
|
singlex peaksearch/chimin 90
|
||||||
singlex peaksearch/chimax 180
|
singlex peaksearch/chimax 180
|
||||||
|
|
||||||
#HKL Settings
|
#HKL Settings
|
||||||
hkl scantolerance 2.500000
|
hkl scantolerance 2.500000
|
||||||
ubcalcint difftheta 0.300000
|
ubcalcint difftheta 0.300000
|
||||||
@ -256,25 +249,21 @@ messref clear
|
|||||||
fmess weak 0
|
fmess weak 0
|
||||||
fmess weakthreshold 20
|
fmess weakthreshold 20
|
||||||
fmess fast 0
|
fmess fast 0
|
||||||
fmess hkllim { -10 -10 10 10 10 10}
|
fmess hkllim -10 -10 10 10 10 10
|
||||||
fmess sttlim { 5 180}
|
fmess sttlim 5 180
|
||||||
|
|
||||||
fmess table clear
|
fmess table clear
|
||||||
cone target { 0 0 0}
|
cone target 0 0 0
|
||||||
cone qscale 1
|
cone qscale 1
|
||||||
cone center unknown
|
cone center unknown
|
||||||
|
|
||||||
simidx sttlim 0.2
|
simidx sttlim 0.2
|
||||||
simidx anglim 0.5
|
simidx anglim 0.5
|
||||||
|
|
||||||
simi preset 0
|
simi preset 0
|
||||||
simi mode monitor
|
simi mode monitor
|
||||||
|
eva targetposition 0
|
||||||
eva targetposition 5
|
eva sign 1
|
||||||
eva sign -1
|
eva softzero 0
|
||||||
eva softzero -2
|
eva softlowerlim -40
|
||||||
eva softlowerlim -38
|
eva softupperlim 40
|
||||||
eva softupperlim 38
|
|
||||||
eva fixed -1
|
eva fixed -1
|
||||||
eva interruptmode 0
|
eva interruptmode 0
|
||||||
eva precision 0.01
|
eva precision 0.01
|
||||||
@ -283,5 +272,4 @@ eva failafter 3
|
|||||||
eva maxretry 3
|
eva maxretry 3
|
||||||
eva ignorefault 0
|
eva ignorefault 0
|
||||||
eva movecount 10
|
eva movecount 10
|
||||||
eva staticoffset -3
|
eva staticoffset 0
|
||||||
|
|
||||||
|
@ -387,11 +387,12 @@ hsetprop /sics/farm/schneggecon readCommand schget
|
|||||||
hsetprop /sics/farm/schneggecon replyCommand schreply
|
hsetprop /sics/farm/schneggecon replyCommand schreply
|
||||||
}
|
}
|
||||||
|
|
||||||
set farm 1
|
set farm 0
|
||||||
|
|
||||||
if {$farm == 1} {
|
if {$farm == 1} {
|
||||||
#-------------- Test new async protocol controller
|
#-------------- Test new async protocol controller
|
||||||
makesctcontroller farmser std localhost:7070
|
makesctcontroller farmser std localhost:8080
|
||||||
|
makesctcomtask farmcom farmser
|
||||||
MakeSICSObj farm TestObj
|
MakeSICSObj farm TestObj
|
||||||
#---------------------------
|
#---------------------------
|
||||||
proc farmparcom {par} {
|
proc farmparcom {par} {
|
||||||
@ -474,7 +475,7 @@ farmser poll /sics/farm/schneggerunning
|
|||||||
hfactory /sics/farm/stone plain spy int
|
hfactory /sics/farm/stone plain spy int
|
||||||
hsetprop /sics/farm/stone read farmparcom stone
|
hsetprop /sics/farm/stone read farmparcom stone
|
||||||
hsetprop /sics/farm/stone parread farmparread
|
hsetprop /sics/farm/stone parread farmparread
|
||||||
farmser poll /sics/farm/stone
|
#farmser poll /sics/farm/stone
|
||||||
|
|
||||||
farmser debug -1
|
farmser debug -1
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user