- 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:
koennecke
2012-12-20 11:32:33 +00:00
parent 4f560552c4
commit 86e246416b
57 changed files with 2025 additions and 290 deletions

View File

@ -1,5 +1,5 @@
#line 467 "histogram.w"
#line 470 "histogram.w"
/*---------------------------------------------------------------------------
H I S T D R I V
@ -72,7 +72,7 @@
void *pPriv;
} HistDriver;
#line 479 "histogram.w"
#line 482 "histogram.w"
#line 232 "histogram.w"
@ -84,7 +84,7 @@
HistInt *DefaultSubSample(pHistDriver self, SConnection *pCon,
int bank, char *command);
#line 480 "histogram.w"
#line 483 "histogram.w"
#endif

View File

@ -1,5 +1,5 @@
#line 440 "histogram.w"
#line 443 "histogram.w"
/*--------------------------------------------------------------------------
H I S T M E M
@ -42,7 +42,7 @@ typedef enum {
eReflect
} OverFlowMode;
#line 460 "histogram.w"
#line 463 "histogram.w"
/*--------------------------------------------------------------------------*/
@ -72,21 +72,23 @@ int HistDoCount(pHistMem self, SConnection * pCon);
int HistBlockCount(pHistMem self, SConnection *pCon);
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 i,int iStart, int iEnd, HistInt *lData);
int GetHistogram(pHistMem self, SConnection *pCon,
int i, int iStart, int iEnd, HistInt * lData,
int iDataLen);
int i,int iStart, int iEnd, HistInt *lData, int iDataLen);
HistInt *GetHistogramPointer(pHistMem self,SConnection *pCon);
int GetHistogramDirect(pHistMem self, SConnection *pCon,
int i, int iStart, int iEnd,
HistInt *lData, int iDataLen);
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 argc, char *argv[]);
@ -95,7 +97,7 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
#line 462 "histogram.w"
#line 465 "histogram.w"
#endif

View File

@ -1,5 +1,5 @@
#line 485 "histogram.w"
#line 488 "histogram.w"
/*---------------------------------------------------------------------------
H I S T M E M -- Internal
@ -23,7 +23,7 @@
pICallBack pCall;
} HistMem;
#line 495 "histogram.w"
#line 498 "histogram.w"
#endif

View File

@ -273,7 +273,7 @@ static int TclExecFunc(SConnection *pCon, SicsInterp *pInter, void *data,
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
return 1;
} else {
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eError );
return 0;
}

View File

@ -58,7 +58,7 @@ int BackgroundCommand(SConnection * pCon, char *command)
return 0;
}
TaskRegister(pServ->pTasker, BackgroundTask, NULL, KillBckTask, self, 1);
TaskRegisterN(pServ->pTasker, self->command, BackgroundTask, NULL, KillBckTask, self, 1);
return 1;
}

View File

@ -489,7 +489,7 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "ERROR: autologging is already active", eError);
return 0;
}
TaskRegister(pServ->pTasker, AutoTask, NULL, NULL, NULL, 1);
TaskRegisterN(pServ->pTasker, "autologger", AutoTask, NULL, NULL, NULL, 1);
SCSendOK(pCon);
iAutoActive = 1;
return 1;

View File

@ -1167,7 +1167,7 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
compStream.avail_in = iDataLen;
compStream.avail_out = iDataLen;
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);
SCWrite(self, outBuf, eError);
return 0;

View File

@ -30,6 +30,8 @@ typedef struct __Counter{
int iCallbackCounter;
int badStatusCount;
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);
CounterMode (*getMode)(struct __Counter *self);
int (*getNMonitor)(struct __Counter *self);

View File

@ -376,7 +376,7 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
self->iStatus = DEVDONE;
/* if no task: start it */
if (self->lTask < 0) {
self->lTask = TaskRegister(self->pTask,
self->lTask = TaskRegisterN(self->pTask,"devexec",
DevExecTask,
DevExecSignal, NULL, self, 1);
self->iEnd = 0;
@ -476,7 +476,7 @@ static int ForceStartDevice(pExeList self, char *name, pObjectDescriptor pDes,
self->iStatus = DEVDONE;
/* if no task: start it */
if (self->lTask < 0) {
self->lTask = TaskRegister(self->pTask,
self->lTask = TaskRegisterN(self->pTask,"devexec",
DevExecTask,
DevExecSignal, NULL, self, 1);
self->iEnd = 0;
@ -962,12 +962,20 @@ int StopByData(pExeList self, void *data)
} else if (pCountInt) {
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");
DevexecLog("FINISHED", pDev->name);
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
self->iStatus = DEVDONE;
SCWrite(self->pOwner, "", eFinish);
*/
return 1;
}
}

View File

@ -308,7 +308,8 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[])
devser->steps = -1; /* no debugging by default */
devser->status = AsconUnconnected;
devser->startTime = -1;
TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0);
TaskRegisterN(pServ->pTasker, AsconHostport(ascon),
DevQueueTask, NULL, NULL, devser, 0);
return devser;
}

View File

@ -388,7 +388,7 @@ int RunDiffScan(pDiffScan self, pScanData pScan,
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);

View File

@ -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
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
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
<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

View File

@ -1175,8 +1175,10 @@ static int printBuffer(pExeMan self, SConnection * pCon,
}
while (fgets(pLine, 511, fd) != NULL) {
DynStringConcat(filePath, pLine);
if(strrchr(pLine,(int)'\n') == NULL){
DynStringConcatChar(filePath,'\n');
}
}
fclose(fd);
SCWrite(pCon, GetCharArray(filePath), eValue);
DeleteDynString(filePath);

View File

@ -19,6 +19,9 @@
extended to support nxscripted file writing: Mark Koennecke, May 2004
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 <assert.h>
@ -428,20 +431,20 @@ static int updateHMFMData(SicsInterp * pSics, SConnection * pCon)
HistInt *data = NULL;
pHistMem pMem = NULL;
pMem = (pHistMem) FindCommandData(pSics, "hm2", "HistMem");
pMem = (pHistMem) FindHM(pSics, "hm2");
if (pMem == NULL) {
return 0;
}
fTimeBin = GetHistTimeBin(pMem, &iTime);
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, MIDDLE);
pMem = (pHistMem) FindCommandData(pSics, "hm1", "HistMem");
pMem = (pHistMem) FindHM(pSics, "hm1");
if (pMem == NULL) {
return 0;
}
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, LOWER);
pMem = (pHistMem) FindCommandData(pSics, "hm3", "HistMem");
pMem = (pHistMem) FindHM(pSics, "hm3");
if (pMem == NULL) {
return 0;
}
@ -567,7 +570,7 @@ static int TOFLambda(SicsInterp * pSics, SConnection * pCon,
float fCenter, fFWHM, fStdDev, fVal;
float fMon, fData, distMonoDet, distFermiDet, tdiff, lambda;
pMem = (pHistMem) FindCommandData(pSics, "hm1", "HistMem");
pMem = (pHistMem) FindHM(pSics, "hm1");
if (pMem == NULL) {
SCWrite(pCon,
"ERROR: need lower detector bank for lambda calculation",
@ -650,7 +653,7 @@ static float calcElastic(SicsInterp * pSics, SConnection * pCon)
pHistMem pMem = NULL;
float fCenter, fFWHM, fStdDev, fVal;
pMem = (pHistMem) FindCommandData(pSics, "hm2", "HistMem");
pMem = (pHistMem) FindHM(pSics, "hm2");
if (pMem == NULL) {
SCWrite(pCon,
"ERROR: need middle detector bank for elastic peak calculation",

View File

@ -647,7 +647,7 @@ void z1FromNormalBeam(double lambda, double omega, double gamma,
/*--------------------------------------------------------------------*/
double circlify(double val)
{
while (val > 360.) {
while (val >= 359.8) {
val -= 360.;
}
while (val < 0.) {

View File

@ -66,7 +66,7 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM,
if (nFrame >= noTimeBins) {
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
Again: be friendly: fix out of range frames
@ -81,7 +81,7 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM,
free(buffer);
return 0;
}
} else if(isSINQHTTP(pHM->pDriv) && noTimeBins > 2){
} else if(!isSecondGen(pHM) && isSINQHTTP(pHM->pDriv) && noTimeBins > 2){
if(sansflag){
snprintf(histCommand,132,"sample:0:%d:%d:%d", iDim[0]*iDim[1], nFrame, nFrame+1);
} else {
@ -244,7 +244,7 @@ int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData,
eError);
return 0;
}
pHM = (pHistMem) FindCommandData(pSics, argv[2], "HistMem");
pHM = (pHistMem) FindHM(pSics, argv[2]);
if (pHM == NULL) {
SCWrite(pCon, "ERROR: Did not find histogram memory", eError);
return 0;

View File

@ -10,6 +10,7 @@
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include "hipadaba.h"
#define ABS(x) (x < 0 ? -(x) : (x))
@ -483,8 +484,32 @@ static unsigned short fletcher16( char *data, size_t len)
result = result << 8 | checkB;
return result ;
}
/*------------------------------------------------------------------------*/
#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)
{
char *data;
@ -928,12 +953,22 @@ static int canCopy(hdbValue * source, hdbValue * target)
return 1;
}
}
if(target->dataType == HIPINTAR &&
(source->dataType == HIPINTAR || source->dataType == HIPINTVARAR)
&& target->arrayLength == source->arrayLength){
return 1;
}
if (target->dataType == HIPFLOATVARAR) {
if (source->dataType == HIPFLOATAR ||
source->dataType == HIPFLOATVARAR) {
return 1;
}
}
if(target->dataType == HIPFLOATAR &&
(source->dataType == HIPFLOATAR || source->dataType == HIPFLOATVARAR)
&& target->arrayLength == source->arrayLength){
return 1;
}
if (source->dataType != target->dataType) {
return 0;
} else {

View File

@ -70,6 +70,7 @@
#include "event.h"
#include "status.h"
#include "site.h"
#include "histmemsec.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*
@ -84,6 +85,27 @@ extern pHistDriver CreateRegressHM(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)
{
pHistMem self = NULL;
@ -715,6 +737,12 @@ long GetHistMonitor(pHistMem self, int i, SConnection * pCon)
void HistDirty(pHistMem self)
{
assert(self);
if(isSecondGen(self)){
SecHistDirty(self);
return;
}
if(self->pDriv != NULL){
updateHMData(self->pDriv->data);
}
@ -724,6 +752,11 @@ void HistDirty(pHistMem self)
const float *GetHistTimeBin(pHistMem self, int *iLength)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistTimeBin(self,iLength);
}
*iLength = getNoOfTimebins(self->pDriv->data);
return getTimeBinning(self->pDriv->data);
}
@ -733,6 +766,10 @@ int GetHistLength(pHistMem self)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistLength(self);
}
return getHMDataLength(self->pDriv->data);
}
@ -827,6 +864,11 @@ int GetHistogram(pHistMem self, SConnection * pCon,
{
assert(self);
if(isSecondGen(self)){
return GetSecHistogram(self,pCon,i,iStart,iEnd,lData,iDataLen);
}
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
@ -883,6 +925,11 @@ HistInt *GetHistogramPointer(pHistMem self, SConnection * pCon)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistogramPointer(self,pCon);
}
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return NULL;

View File

@ -10,10 +10,17 @@
* copyright: see file COPYRIGHT
*
* Mark Koennecke, May 2009
*
* Added bridging routines implementing first gen HM interfaces
*
* Mark Koennecke, December 2012
*/
#include <sics.h>
#include <sicshipadaba.h>
#include <counter.h>
#include "HistMem.h"
#include "HistMem.i"
#include "arrayutil.h"
#define CONFIG 1005
@ -82,6 +89,45 @@ static int ResetCmd(pSICSOBJ ccmd, SConnection * pCon,
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,
Hdb * cmdNode, Hdb * par[], int nPar)
{
@ -124,6 +170,96 @@ static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon,
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,
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,"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
*/
@ -245,6 +387,10 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
AddSICSHdbPar(child, "start", usMugger, MakeHdbFloat(10.));
AddSICSHdbPar(child, "step", usMugger, MakeHdbFloat(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;
}
/*===========================================================================
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;
}

View File

@ -17,4 +17,12 @@
int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
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_*/

View File

@ -443,6 +443,9 @@ $\langle$Protos {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int HistBlockCount(pHistMem self, SConnection *pCon);@\\
\mbox{}\verb@ void HistDirty(pHistMem self); @\\
\mbox{}\verb@@\\
\mbox{}\verb@ int isSecondGen(pHistMem self);@\\
\mbox{}\verb@ pHistMem FindHM(SicsInterp *pSics, char *name);@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}

View File

@ -347,6 +347,9 @@ controlled by the following functions:
int HistBlockCount(pHistMem self, SConnection *pCon);
void HistDirty(pHistMem self);
int isSecondGen(pHistMem self);
pHistMem FindHM(SicsInterp *pSics, char *name);
@}
The first four functions are simple parameter enquiry and manipulation
functions. GetHistMonitor returns the count on monitor number i for the

View File

@ -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 \
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.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
COUNTEROBJ = countdriv.o simcter.o counter.o

10
nread.c
View File

@ -1090,6 +1090,7 @@ static int CommandAcceptCB(int handle, void *userData)
{
SConnection *pCon = NULL;
pCommandCBData usData = NULL;
char buffer[80];
pCon = SCreateConnection(pServ->pSics, handle, 3);
usData = malloc(sizeof(CommandCBData));
@ -1104,7 +1105,9 @@ static int CommandAcceptCB(int handle, void *userData)
}
usData->pCon = pCon;
usData->state = COLLECT;
TaskRegister(pServ->pTasker,
snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
TaskRegisterN(pServ->pTasker,
buffer,
SCTaskFunction,
SCSignalFunction, SCDeleteConnection, pCon, 1);
ANETsetReadCallback(handle, CommandDataCB, usData, killCommandCBData);
@ -1293,6 +1296,7 @@ static int TelnetAcceptCB(int handle, void *userData)
SConnection *pCon = NULL;
pCommandCBData usData = NULL;
pTelTask pTel = NULL;
char buffer[80];
pCon = SCreateConnection(pServ->pSics, handle, 3);
usData = malloc(sizeof(CommandCBData));
@ -1316,7 +1320,9 @@ static int TelnetAcceptCB(int handle, void *userData)
}
/* register connection and task */
pCon->iTelnet = 1;
TaskRegister(pServ->pTasker,
snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
TaskRegisterN(pServ->pTasker,
buffer,
TelnetTask, TelnetSignal, DeleteTelnet, pTel, 1);
ANETsetReadCallback(handle, ANETTelnetProcess,
usData, killCommandCBData);

View File

@ -179,7 +179,8 @@ int InitServer(char *file, pServer * pServ)
assert((pReader =
CreateNetReader(self, iPasswordTimeOut,
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);
self->pReader = pReader;
@ -244,17 +245,18 @@ int InitServer(char *file, pServer * pServ)
/* install environment monitor */
self->pMonitor = GetEnvMon(self->pSics);
TaskRegister(self->pTasker,
TaskRegisterN(self->pTasker,"EV Monitor",
EnvMonTask, EnvMonSignal, NULL, self->pMonitor, 1);
/* install performance monitor */
pMon = CreatePerfMon(20);
AddCommand(self->pSics, "Performance", PerfMonWrapper, DeletePerfMon,
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 */
pMon = CreatePerfMon(2);
TaskRegister(self->pTasker, PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
TaskRegisterN(self->pTasker,"perfmon2",
PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
/* install telnet port */
@ -469,7 +471,7 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData,
SetStatus(eUserWait);
sWait.dFinish = DoubleTime() + (double)fVal;
sWait.iEnd = 0;
lID = TaskRegister(pTask, WaitTask, WaitSignal, NULL, &sWait, 1);
lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, 1);
TaskWait(pTask, lID);
SetStatus(eOld);
if (SCGetInterrupt(pCon) != eContinue) {

View File

@ -54,7 +54,7 @@ int NetWatchInit(void)
return 0;
memset(instance, 0, sizeof(NetWatch));
instance->lMagic = NWMAGIC;
TaskRegister(pServ->pTasker, NetWatchTask, NULL, NULL, NULL, 1);
TaskRegisterN(pServ->pTasker,"nwatch", NetWatchTask, NULL, NULL, NULL, 1);
}
return 1;
}

View File

@ -81,7 +81,7 @@ static int CountCallback(int iEvent, void *pEventData, void *pUser)
self->nextUpdate = time(NULL) + self->updateIntervall;
self->iEnd = 0;
self->pCon = pCon;
TaskRegister(pServ->pTasker, UpdateTask, NULL, NULL, self, 1);
TaskRegisterN(pServ->pTasker, "NXupdater", UpdateTask, NULL, NULL, self, 1);
return 1;
} else if (iEvent == COUNTEND) {
self->iEnd = 1;

1
ofac.c
View File

@ -169,6 +169,7 @@ static void InitIniCommands(SicsInterp * pInter)
SCMD("SicsAlias", SicsAlias);
SCMD("SicsUser", PWSicsUser);
SCMD("TokenInit", TokenInit);
SCMD("MakeTask", TaskOBJFactory);
SCMD("UpdateFactory", UpdateFactory);
SCMD("VarMake", VarFactory);
SCMD("VelocitySelector", VelSelFactory);

View File

@ -166,7 +166,8 @@ static int StartOscillation(pOscillator self, SConnection * pCon)
/*
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);
if (self->taskID < 0) {
SCWrite(pCon, "ERROR: failed to start oscillation task", eError);

View File

@ -953,7 +953,7 @@ static RemServer *RemServerInit(char *name, char *host, int port)
remserver->taskActive = 1;
remserver->interestActive = 0;
remserver->forwardMessages = 1;
TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill,
TaskRegisterN(pServ->pTasker,name, RemServerTask, NULL, RemServerKill,
remserver, 1);
return remserver;
}

View File

@ -101,8 +101,7 @@ static int COGCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 0;
}
hm = FindCommandData(pServ->pSics,
par[0]->value.v.text, "HistMem");
hm = FindHM(pServ->pSics, par[0]->value.v.text);
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
return 0;
@ -137,8 +136,7 @@ static int COCCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 0;
}
hm = FindCommandData(pServ->pSics,
par[0]->value.v.text, "HistMem");
hm = FindHM(pServ->pSics, par[0]->value.v.text);
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
return 0;
@ -173,8 +171,7 @@ static int StatCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 0;
}
hm = FindCommandData(pServ->pSics,
par[0]->value.v.text, "HistMem");
hm = FindHM(pServ->pSics, par[0]->value.v.text);
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
return 0;

View File

@ -15,6 +15,7 @@
#include "macro.h"
#include "syncedprot.h"
#include "scriptcontext.h"
#include "sctcomtask.h"
typedef struct ContextItem {
struct ContextItem *next;
@ -862,7 +863,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
return hdbContinue;
}
static char *ParText(Hdb * cmdNode, char *name,
char *ParText(Hdb * cmdNode, char *name,
int nPar, char *defaultValue)
{
Hdb *par;
@ -1412,15 +1413,6 @@ static char *TransactionHandler(void *actionData, char *lastReply,
return st->command;
} else {
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) {
lastReply = "";
}
@ -1487,12 +1479,6 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con,
TransactionHandler, SctTransactMatch, NULL, NULL);
while (st->sent != 2) {
TaskYield(pServ->pTasker);
/* not yet tested:
if (SCGetInterrupt(con) != eContinue) {
DevUnschedule(c->devser, st, TransactionHandler, SctTransactMatch);
break;
}
*/
}
if (st->reply != NULL) {
SCWrite(con,st->reply,eValue);
@ -1722,7 +1708,7 @@ static void SctKillController(void *c)
}
if (pServ->pTasker) {
TaskRegister(pServ->pTasker, SctDeferredTask, NULL, SctDeferredFree,
TaskRegisterN(pServ->pTasker,"killsct", SctDeferredTask, NULL, SctDeferredFree,
controller, 0);
} else {
free(controller);
@ -1899,6 +1885,7 @@ void SctInit(void)
sct->desc = CreateDescriptor("ScriptContext");
AddCommand(pServ->pSics, "sct", SctCommand, SctKill, sct);
AddCmd("makesctcontroller", SctMakeController);
AddCmd("makesctcomtask", SctMakeComTask);
}
int SctVerbose(SctController * c)
@ -1906,3 +1893,15 @@ int SctVerbose(SctController * c)
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;
}

View File

@ -35,5 +35,10 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node,
* \return 1 for verbose, 0 for silent
*/
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

517
sctcomtask.c Normal file
View 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
View 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

View File

@ -166,7 +166,7 @@ static long SCTDRIVSetValue(void *data, SConnection * pCon, float val)
OKOK or HWIdle when the motor finished driving
HWFault when a hardware problem ocurred
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
issues with the motor
------------------------------------------------------------------*/

View File

@ -194,7 +194,7 @@ int SerialSicsExecute(void **pData, char *pCommand,
control.data = CreateDynString(1024, 1024);
/* start task */
lTask = TaskRegister(pServ->pTasker,
lTask = TaskRegisterN(pServ->pTasker,"serialwait",
SWTask, SWSignal, NULL, &control, 1);
/* wait for it to end */
TaskWait(pServ->pTasker, lTask);

View File

@ -207,7 +207,7 @@ int MakeCron(SConnection * pCon, SicsInterp * pSics, void *pData,
}
pNew->stat = StatisticsNew(cmd);
TaskRegister(pServ->pTasker, CronTask, CronSignal, KillCron, pNew, 1);
TaskRegisterN(pServ->pTasker,"sicscron", CronTask, CronSignal, KillCron, pNew, 1);
SCSendOK(pCon);
return 1;
}

View File

@ -11,6 +11,8 @@
Mark Koennecke, June 2003
added addto. Mark Koennecke, August 2009
Make Hipadaba compatible, Mark Koennecke, November 2012
----------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
@ -47,7 +49,7 @@ static void KillSICSData(void *pData)
}
/*---------------------------------------------------------------------*/
pSICSData createSICSData(void)
pSICSData createSICSData(char *name)
{
pSICSData pNew = NULL;
@ -63,6 +65,13 @@ pSICSData createSICSData(void)
KillSICSData(pNew);
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->dataType, 0, 1024 * sizeof(char));
pNew->currentDataSize = 1024;
@ -1115,7 +1124,7 @@ int SICSDataFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
strtolower(argv[2]);
if (strcmp(argv[1], "new") == 0) {
self = createSICSData();
self = createSICSData(argv[2]);
if (self == NULL) {
SCWrite(pCon, "ERROR: not enough memory to create SICSData", eError);
return 0;

View File

@ -28,15 +28,17 @@ typedef struct {
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);
int SICSDataFactory(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[]);
void *pData,
int argc, char *argv[]);
int SICSDataAction(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[]);
void *pData,
int argc, char *argv[]);
void clearSICSData(pSICSData self);
int getSICSDataInt(pSICSData self, int pos, int *value);

View File

@ -39,7 +39,7 @@ This object exports the following functions:
@d sidafunc @{
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);

View File

@ -76,7 +76,7 @@ int SicsExit(SConnection * pCon, SicsInterp * pInterp, void *pData,
if (SCMatchRights(pCon, usMugger)) { /* only Muggers are allowed to do it */
SetInterrupt(eEndServer);
lID = TaskRegister(pTask, WaitTask, NULL, NULL, NULL, 1);
lID = TaskRegisterN(pTask,"exittask", WaitTask, NULL, NULL, NULL, 1);
TaskWait(pTask, lID);
TaskStop(pTask);
return 1;

View File

@ -36,6 +36,7 @@
#include <macro.h>
#include "commandlog.h"
#include "arrayutil.h"
#include "HistMem.h"
#define MAX_HDB_PATH 1024
@ -2503,6 +2504,50 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics,
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,
int argc, char *argv[])
@ -2984,6 +3029,171 @@ static int isArrayNode(pHdb node)
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(&copyData, &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(&copyData, &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,
int argc, char *argv[])
{
@ -3062,6 +3272,16 @@ static int HdbArrayNode(SConnection * pCon, SicsInterp * pSics, void *pData,
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]);
if(idx < 0 || idx >= node->value.arrayLength ){
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]);
break;
}
NotifyHipadabaPar(node, pCon);
SCSendOK(pCon);
return 1;
}
@ -3408,6 +3627,27 @@ static int ListSICSHdbProperty(SConnection * pCon, SicsInterp * pSics,
DeleteDynString(data);
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)
@ -3432,7 +3672,6 @@ static pHdb matchHdbProp(pHdb root, char *propname, char *buffer)
return NULL;
}
/*---------------------------------------------------------------------------*/
static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics,
void *pData, int argc, char *argv[])
@ -3495,6 +3734,7 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics,
AddCommand(pSics, "hget", GetHdbNode, NULL, NULL);
AddCommand(pSics, "hval", GetHdbVal, NULL, NULL);
AddCommand(pSics, "hzipget", ZipGetHdbNode, NULL, NULL);
AddCommand(pSics, "hzipread", ZipReadHdbNode, NULL, NULL);
AddCommand(pSics, "hlist", ListHdbNode, NULL, NULL);
AddCommand(pSics, "hnotify", AutoNotifyHdbNode, 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, "hmatchprop", MatchHdbProperty, NULL, NULL);
AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL);
AddCommand(pSics, "hcallnotify",CallNotify, NULL, NULL);
InstallSICSPoll(pCon, pSics, pData, argc, argv);
poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll");

View File

@ -36,56 +36,6 @@ void DefaultFree(void *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)
{
@ -144,40 +94,6 @@ int SaveSICSOBJ(void *data, char *name, FILE * fd)
}
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)
{

View File

@ -379,7 +379,7 @@ int InstallSICSPoll(SConnection * pCon, SicsInterp * pSics, void *pData,
pNew->pCon = defCon;
pNew->nPoll = 3;
TaskRegister(pServ->pTasker, PollTask, SicsPollSignal, NULL, pNew, 10);
TaskRegisterN(pServ->pTasker,"sicspoll", PollTask, SicsPollSignal, NULL, pNew, 10);
if (argc > 1) {
AddCommand(pSics, argv[1], SICSPollWrapper, killSicsPoll, pNew);

View File

@ -12,4 +12,5 @@
#include "singlediff.h"
void initializeSingleBisecting(pSingleDiff diff);
void initializeSingleBisectingOrion(pSingleDiff diff);
#endif /*SINGELBI_H_ */

View File

@ -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,
double *hkl, double *settings)
@ -282,6 +322,60 @@ static int calculateBiSettings(pSingleDiff self,
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)
{
@ -471,3 +565,9 @@ void initializeSingleBisecting(pSingleDiff diff)
diff->calcUBFromThree = calcBiUBFromThree;
diff->calcZ1 = calcBiZ1;
}
/*--------------------------------------------------------------------*/
void initializeSingleBisectingOrion(pSingleDiff diff)
{
initializeSingleBisecting(diff);
diff->calculateSettings = calculateBiSettingsOrion;
}

View File

@ -227,6 +227,7 @@ static int findModeIndex(char *mode)
"nb",
"tas",
"binb",
"bio",
NULL
};
int count = 0;
@ -254,6 +255,7 @@ static hdbCallbackReturn SetModeCB(pHdb node, void *userData,
pTest = trim(set->v->v.text);
pCon = set->callData;
modeIdx = findModeIndex(pTest);
switch (modeIdx) {
case Bisecting:
if (priv->chi == NULL || priv->om == NULL || priv->phi == NULL
@ -269,6 +271,22 @@ static hdbCallbackReturn SetModeCB(pHdb node, void *userData,
initializeSingleBisecting(priv->diffractometer);
return hdbContinue;
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:
if (priv->nu == NULL || priv->om == NULL || priv->stt == NULL) {
if (pCon != NULL) {
@ -874,8 +892,12 @@ pSICSOBJ SXGetReflectionList()
SingleXModes SXGetMode()
{
pSingleX priv = (pSingleX) singlex->pPrivate;
if(priv->mode == BiO){
return Bisecting;
} else {
return priv->mode;
}
}
/*---------------------------------------------------------------------------*/
T_SgInfo *SXGetSpaceGroup()

View File

@ -35,7 +35,7 @@ double SXGetLambda();
pSICSOBJ SXGetReflectionList();
typedef enum {
Bisecting, NB, Tas, BiNB,
Bisecting, NB, Tas, BiNB, BiO,
} SingleXModes;
SingleXModes SXGetMode();

View File

@ -297,5 +297,5 @@ void StatusFileDirty(void)
/*-----------------------------------------------------------------------*/
void StatusFileInit(void)
{
TaskRegister(pServ->pTasker, StatusFileTask, NULL, NULL, NULL, 0);
TaskRegisterN(pServ->pTasker, "statusfile", StatusFileTask, NULL, NULL, NULL, 0);
}

View File

@ -723,11 +723,11 @@ static int calculateQMAndDrive(ptasMot self, SConnection * pCon)
&angles);
switch (status) {
case ENERGYTOBIG:
SCWrite(pCon, "ERROR: desired energy to big", eError);
SCWrite(pCon, "ERROR: desired energy to big", eLogError);
return HWFault;
break;
case TRIANGLENOTCLOSED:
SCWrite(pCon, "ERROR: cannot close scattering triangle", eError);
SCWrite(pCon, "ERROR: cannot close scattering triangle", eLogError);
return HWFault;
break;
default:

216
task.c
View File

@ -10,9 +10,15 @@
NO WARRANTIES OF ANY KIND WHATSOEVER TAKEN BY ME OR MY EMPLOYER.
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 <assert.h>
#include <time.h>
#include <stdio.h>
#include "fortify.h"
#include "task.h"
#define READY 1
@ -21,8 +27,11 @@
/*--------------------------------------------------------------------------*/
typedef struct __TaskHead {
long lID;
long groupID;
int iStatus;
long lWait;
char *name;
time_t start_time;
TaskFunc pRun;
SignalFunc pSignal;
void *pData;
@ -34,7 +43,7 @@ typedef struct __TaskHead {
typedef struct __TaskMan {
int iID;
int iStop;
pTaskHead pCurrent;
pTaskHead pCurrent; /* Think trice before you interfere with this! */
pTaskHead pHead;
} TaskMan;
/*---------------------------------------------------------------------------*/
@ -42,7 +51,7 @@ static long lIDMama = 0L;
#define TASKERID 123399
/*---------------------------------------------------------------------------*/
static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal,
void *pData, TaskKillFunc pKill)
{
pTaskHead pNew = NULL;
@ -53,6 +62,8 @@ static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
}
memset(pNew, 0, sizeof(TaskHead));
pNew->name = strdup(name);
pNew->start_time = time(NULL);
pNew->pRun = pTask;
pNew->pSignal = pSignal;
pNew->pData = pData;
@ -60,6 +71,10 @@ static pTaskHead MakeTaskHead(TaskFunc pTask, SignalFunc pSignal,
pNew->lID = lIDMama++;
pNew->iStatus = READY;
if(lIDMama < 0){
lIDMama = 0;
}
return pNew;
}
@ -73,6 +88,9 @@ static void DeleteTaskHead(pTaskHead self)
self->pKill(self->pData);
}
}
if(self->name != NULL){
free(self->name);
}
/* unlink */
if (self->pPrevious != NULL) {
self->pPrevious->pNext = self->pNext;
@ -105,7 +123,7 @@ int TaskerInit(pTaskMan * self)
pNew->iID = TASKERID;
/* create a dummy task as start point */
pDummyTask = MakeTaskHead(DummyTask, NULL, NULL, NULL);
pDummyTask = MakeTaskHead("init",DummyTask, NULL, NULL, NULL);
if (!pDummyTask) {
free(pNew);
return 0;
@ -140,10 +158,15 @@ int TaskerDelete(pTaskMan * pData)
*pData = NULL;
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 TaskRegisterN(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal,
TaskKillFunc pKill, void *pData, int iPriority)
{
pTaskHead pNew = NULL;
@ -151,7 +174,7 @@ long TaskRegister(pTaskMan self, TaskFunc pTask, SignalFunc pSignal,
assert(self->iID == TASKERID);
assert(pTask);
pNew = MakeTaskHead(pTask, pSignal, pData, pKill);
pNew = MakeTaskHead(name, pTask, pSignal, pData, pKill);
if (!pNew) {
return -1;
}
@ -166,7 +189,6 @@ long TaskRegister(pTaskMan self, TaskFunc pTask, SignalFunc pSignal,
return pNew->lID;
}
/*-------------------------------------------------------------------------*/
static void IncrTaskPointer(pTaskMan self)
{
@ -359,6 +381,10 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData)
pCurrent = pNext;
pNext = pCurrent->pNext;
if (pCurrent->pRun == pTaskRun && pCurrent->pData == pData) {
if(pCurrent == self->pCurrent){
/* cannot kill myself */
return;
}
/* unlink */
if (pCurrent->pPrevious != NULL) {
pCurrent->pPrevious->pNext = pCurrent->pNext;
@ -366,8 +392,184 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData)
if (pCurrent->pNext != NULL) {
pCurrent->pNext->pPrevious = pCurrent->pPrevious;
}
if(pCurrent->name != NULL){
free(pCurrent->name);
}
free(pCurrent);
}
}
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
View File

@ -78,6 +78,23 @@ long TaskRegister(pTaskMan self, TaskFunc pTaskRun,
On Success a positive value denoting the ID of the task 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);
/*
@ -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
*/
/*-------------------------------------------------------------------------*/
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

185
taskobj.c Normal file
View 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
View 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_*/

View File

@ -1,4 +1,3 @@
exe batchpath ./
exe syspath ./
@ -212,27 +211,22 @@ tasub outofplane 1
tasub const ki
tasub ss 1
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 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 update
#----- MultiMotor sa
sa recovernampos noeff a3 24 a4 48
ref anglesheader stt,om,chi,phi
ref clear
singlex cell { 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 planenormal { 0 0 0}
singlex cell 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 planenormal 0 0 0
singlex mode bi
singlex spacegroup P
singlex peaksearch {}
singlex peaksearch
singlex peaksearch/min2t 5
singlex peaksearch/step2t 1
singlex peaksearch/max2t 15
@ -244,7 +238,6 @@ singlex peaksearch/phimin 0
singlex peaksearch/phimax 180
singlex peaksearch/chimin 90
singlex peaksearch/chimax 180
#HKL Settings
hkl scantolerance 2.500000
ubcalcint difftheta 0.300000
@ -256,25 +249,21 @@ messref clear
fmess weak 0
fmess weakthreshold 20
fmess fast 0
fmess hkllim { -10 -10 10 10 10 10}
fmess sttlim { 5 180}
fmess hkllim -10 -10 10 10 10 10
fmess sttlim 5 180
fmess table clear
cone target { 0 0 0}
cone target 0 0 0
cone qscale 1
cone center unknown
simidx sttlim 0.2
simidx anglim 0.5
simi preset 0
simi mode monitor
eva targetposition 5
eva sign -1
eva softzero -2
eva softlowerlim -38
eva softupperlim 38
eva targetposition 0
eva sign 1
eva softzero 0
eva softlowerlim -40
eva softupperlim 40
eva fixed -1
eva interruptmode 0
eva precision 0.01
@ -283,5 +272,4 @@ eva failafter 3
eva maxretry 3
eva ignorefault 0
eva movecount 10
eva staticoffset -3
eva staticoffset 0

View File

@ -387,11 +387,12 @@ hsetprop /sics/farm/schneggecon readCommand schget
hsetprop /sics/farm/schneggecon replyCommand schreply
}
set farm 1
set farm 0
if {$farm == 1} {
#-------------- Test new async protocol controller
makesctcontroller farmser std localhost:7070
makesctcontroller farmser std localhost:8080
makesctcomtask farmcom farmser
MakeSICSObj farm TestObj
#---------------------------
proc farmparcom {par} {
@ -474,7 +475,7 @@ farmser poll /sics/farm/schneggerunning
hfactory /sics/farm/stone plain spy int
hsetprop /sics/farm/stone read farmparcom stone
hsetprop /sics/farm/stone parread farmparread
farmser poll /sics/farm/stone
#farmser poll /sics/farm/stone
farmser debug -1