Implement task priorities and message queues
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* This is the SICS interface object to the tasker module
|
||||
*
|
||||
* copyright: GPL
|
||||
*
|
||||
*
|
||||
* Mark Koennecke, December 2012
|
||||
*/
|
||||
#include <sics.h>
|
||||
@@ -15,6 +15,37 @@ typedef struct {
|
||||
char *scriptName;
|
||||
SConnection *con;
|
||||
} TclFunc, *pTclFunc;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void TaskObjLogFunc(eTaskLogLevel lvl, const char *buf)
|
||||
{
|
||||
OutCode eOut;
|
||||
|
||||
switch (lvl) {
|
||||
case eTaskLogNone:
|
||||
return;
|
||||
case eTaskLogInfo:
|
||||
eOut = eValue;
|
||||
break;
|
||||
case eTaskLogDebug:
|
||||
eOut = eValue;
|
||||
break;
|
||||
case eTaskLogWarning:
|
||||
eOut = eWarning;
|
||||
break;
|
||||
case eTaskLogError:
|
||||
eOut = eError;
|
||||
break;
|
||||
case eTaskLogFatal:
|
||||
eOut = eError;
|
||||
break;
|
||||
default:
|
||||
eOut = eValue;
|
||||
break;
|
||||
}
|
||||
SICSLogWrite(buf, eOut);
|
||||
return;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
@@ -28,8 +59,8 @@ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
SCWrite(pCon,"ERROR: out of memory in ListCmd", eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
|
||||
"Task", "Start_Time", "ID");
|
||||
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)){
|
||||
@@ -39,8 +70,8 @@ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pPtr = stptok(pPtr,time,sizeof(time),"|");
|
||||
pPtr = stptok(pPtr,id,sizeof(id),"|");
|
||||
pPtr = stptok(pPtr,gid,sizeof(gid),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s %10s",
|
||||
name,time,id,gid);
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s %10s",
|
||||
name,time,id,gid);
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
free(pDes);
|
||||
@@ -51,6 +82,103 @@ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int PerfCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
pDynString result = NULL;
|
||||
char buffer[256], *pDes, *pPtr, name[80];
|
||||
char runs[80], waits[80], yields[80], cpu[80], wall[80], yield[80];
|
||||
pTaskHead it = NULL;
|
||||
|
||||
result = CreateDynString(128,128);
|
||||
if(result == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in PerfCmd", eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
"Task", "Runs", "Waits", "Yields", "Processor", "Elapsed", "Yield");
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||
pDes = TaskDetail(it);
|
||||
if(pDes != NULL){
|
||||
pPtr = stptok(pDes,name,sizeof(name),"|");
|
||||
pPtr = stptok(pPtr,runs,sizeof(runs),"|");
|
||||
pPtr = stptok(pPtr,waits,sizeof(waits),"|");
|
||||
pPtr = stptok(pPtr,yields,sizeof(yields),"|");
|
||||
pPtr = stptok(pPtr,cpu,sizeof(cpu),"|");
|
||||
pPtr = stptok(pPtr,wall,sizeof(wall),"|");
|
||||
pPtr = stptok(pPtr,yield,sizeof(yield),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
name,runs,waits,yields,cpu,wall,yield);
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
free(pDes);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(result),eValue);
|
||||
DeleteDynString(result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int StackCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
pDynString result = NULL;
|
||||
char buffer[256], *pDes, *pPtr, name[80];
|
||||
char runs[80], waits[80], yields[80], cpu[80], wall[80], yield[80];
|
||||
pTaskHead it = NULL;
|
||||
pTaskHead *stack = NULL;
|
||||
int i, stackDepth;
|
||||
|
||||
result = CreateDynString(128,128);
|
||||
if(result == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in StackCmd", eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
"Task", "Runs", "Waits", "Yields", "Processor", "Elapsed", "Yield");
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
stackDepth = TaskGetStack(pServ->pTasker, NULL);
|
||||
if (stackDepth <= 0) {
|
||||
SCWrite(pCon,"No task stack", eValue);
|
||||
DeleteDynString(result);
|
||||
return 0;
|
||||
}
|
||||
stack = calloc(stackDepth, sizeof(pTaskHead));
|
||||
if (stack == NULL) {
|
||||
SCWrite(pCon,"ERROR: out of memory in StackCmd", eError);
|
||||
DeleteDynString(result);
|
||||
return 0;
|
||||
}
|
||||
stackDepth = TaskGetStack(pServ->pTasker, stack);
|
||||
for (i = 0; i < stackDepth; ++i) {
|
||||
it = stack[i];
|
||||
pDes = TaskDetail(it);
|
||||
if(pDes != NULL){
|
||||
pPtr = stptok(pDes,name,sizeof(name),"|");
|
||||
pPtr = stptok(pPtr,runs,sizeof(runs),"|");
|
||||
pPtr = stptok(pPtr,waits,sizeof(waits),"|");
|
||||
pPtr = stptok(pPtr,yields,sizeof(yields),"|");
|
||||
pPtr = stptok(pPtr,cpu,sizeof(cpu),"|");
|
||||
pPtr = stptok(pPtr,wall,sizeof(wall),"|");
|
||||
pPtr = stptok(pPtr,yield,sizeof(yield),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
name,runs,waits,yields,cpu,wall,yield);
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
free(pDes);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(result),eValue);
|
||||
DeleteDynString(result);
|
||||
free(stack);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
@@ -74,6 +202,126 @@ static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int InfoCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
char buffer[256];
|
||||
char *pArgs = NULL, *pPtr;
|
||||
char task_task[20], task_name[80], task_info[80];
|
||||
pTaskHead it = NULL;
|
||||
|
||||
if (nPar < 1) {
|
||||
SCWrite(pCon,"Info.args: NULL", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SCMatchRights(pCon,usMugger)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pArgs = par[0]->value.v.text;
|
||||
pPtr = pArgs;
|
||||
while (pPtr && *pPtr == '/') ++pPtr;
|
||||
pPtr = stptok(pPtr, task_task, sizeof(task_task), "/");
|
||||
if (strcasecmp(task_task, "task") != 0) {
|
||||
SCPrintf(pCon, eError, "ERROR: task info must start with /task/, not %s in %s",
|
||||
task_task, pArgs);
|
||||
return 0;
|
||||
}
|
||||
while (pPtr && *pPtr == '/') ++pPtr;
|
||||
pPtr = stptok(pPtr, task_name, sizeof(task_name), "/");
|
||||
while (pPtr && *pPtr == '/') ++pPtr;
|
||||
if (strcasecmp(task_name, "count") == 0) {
|
||||
int count = 0;
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||
++count;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "Task.Count = %d", count);
|
||||
return 1;
|
||||
} else if (strcasecmp(task_name, "list") == 0) {
|
||||
int count = 0;
|
||||
pDynString result = CreateDynString(100, 100);
|
||||
char txt[80], *pDes;
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)) {
|
||||
pDes = TaskDescription(it);
|
||||
if (pDes != NULL) {
|
||||
char buffer[256], *pPtr, name[80], time[80], id[80], gid[80];
|
||||
pPtr = stptok(pDes,name,sizeof(name),"|");
|
||||
pPtr = stptok(pPtr,time,sizeof(time),"|");
|
||||
pPtr = stptok(pPtr,id,sizeof(id),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%s", id);
|
||||
if (count++ > 0)
|
||||
DynStringConcatChar(result,' ');
|
||||
DynStringConcat(result, buffer);
|
||||
free(pDes);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(result), eValue);
|
||||
DeleteDynString(result);
|
||||
return 1;
|
||||
} else if (strcasecmp(task_name, "current") == 0) {
|
||||
it = TaskIteratorCurrent(pServ->pTasker);
|
||||
} else if (strcasecmp(task_name, "by-id") == 0) {
|
||||
pPtr = stptok(pPtr, task_name, sizeof(task_name), "/");
|
||||
while (*pPtr == '/') ++pPtr;
|
||||
it = TaskIteratorByID(pServ->pTasker, atol(task_name));
|
||||
} else if (strcasecmp(task_name, "by-name") == 0) {
|
||||
pPtr = stptok(pPtr, task_name, sizeof(task_name), "/");
|
||||
while (*pPtr == '/') ++pPtr;
|
||||
it = TaskIteratorByName(pServ->pTasker, task_name);
|
||||
} else {
|
||||
SCPrintf(pCon, eError, "ERROR: expected current, by-name or by-id in %s", pArgs);
|
||||
return 0;
|
||||
}
|
||||
if (it == NULL) {
|
||||
SCPrintf(pCon, eError, "ERROR: task not found in %s", pArgs);
|
||||
return 0;
|
||||
}
|
||||
pPtr = stptok(pPtr, task_info, sizeof(task_info), "/");
|
||||
if (strcasecmp(task_info, "all") == 0) {
|
||||
char *pDet, *pDes;
|
||||
pDes = TaskDescription(it);
|
||||
pDet = TaskDetail(it);
|
||||
SCPrintf(pCon, eValue, "%s %s", pDes, pDet);
|
||||
free(pDes);
|
||||
free(pDet);
|
||||
} else {
|
||||
SCPrintf(pCon, eLog, "Info.args: %s", par[0]->value.v.text);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int LogCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
|
||||
if (nPar < 1) {
|
||||
SCWrite(pCon,"ERROR: need log level (none,debug,info,warning,error,fatal)", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SCMatchRights(pCon,usMugger)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcasecmp("None", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogNone);
|
||||
} else if (strcasecmp("Debug", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogDebug);
|
||||
} else if (strcasecmp("Info", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogInfo);
|
||||
} else if (strcasecmp("Warning", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogWarning);
|
||||
} else if (strcasecmp("Error", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogError);
|
||||
} else if (strcasecmp("Fatal", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogFatal);
|
||||
}
|
||||
TaskSetLogFunc((TaskLogFunc) TaskObjLogFunc);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int TclTaskFunction(void *pData)
|
||||
{
|
||||
@@ -85,11 +333,11 @@ static int TclTaskFunction(void *pData)
|
||||
|
||||
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));
|
||||
*/
|
||||
@@ -150,21 +398,21 @@ static int RunCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
data->scriptName = strdup(par[0]->value.v.text);
|
||||
TaskRegisterN(pServ->pTasker,
|
||||
data->scriptName,
|
||||
TclTaskFunction,
|
||||
TclFuncSignal,
|
||||
KillTclFunc,
|
||||
data, 0);
|
||||
TclTaskFunction,
|
||||
TclFuncSignal,
|
||||
KillTclFunc,
|
||||
data, TASK_PRIO_HIGH);
|
||||
traceSys("task","Started task %s",data->scriptName);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
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;
|
||||
@@ -172,7 +420,9 @@ int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy,
|
||||
MakeSICSFunc(ListCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "perf", usSpy,
|
||||
MakeSICSFunc(PerfCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy,
|
||||
MakeSICSFunc(KillCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
@@ -186,7 +436,7 @@ int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
SetHdbProperty(cmd,"priv","spy");
|
||||
node = MakeSICSHdbPar("script",usSpy,MakeHdbText("banana"));
|
||||
AddHipadabaChild(cmd,node,NULL);
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -195,7 +445,7 @@ void InitTaskOBJ()
|
||||
{
|
||||
pSICSOBJ pNew = NULL;
|
||||
pHdb cmd = NULL, node;
|
||||
|
||||
|
||||
|
||||
pNew = MakeSICSOBJv("task", "TaskOBJ", HIPNONE, usInternal);
|
||||
if (pNew == NULL) {
|
||||
@@ -205,7 +455,25 @@ void InitTaskOBJ()
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy,
|
||||
MakeSICSFunc(ListCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "perf", usSpy,
|
||||
MakeSICSFunc(PerfCmd));
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "stack", usSpy,
|
||||
MakeSICSFunc(StackCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "info", usSpy,
|
||||
MakeSICSFunc(InfoCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
SetHdbProperty(cmd,"priv","spy");
|
||||
node = MakeSICSHdbPar("args",usSpy,MakeHdbText("banana"));
|
||||
AddHipadabaChild(cmd,node,NULL);
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "log", usSpy,
|
||||
MakeSICSFunc(LogCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
SetHdbProperty(cmd,"priv","spy");
|
||||
node = MakeSICSHdbPar("level",usSpy,MakeHdbText("banana"));
|
||||
AddHipadabaChild(cmd,node,NULL);
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy,
|
||||
MakeSICSFunc(KillCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
@@ -222,5 +490,5 @@ void InitTaskOBJ()
|
||||
|
||||
AddCommand(pServ->pSics,
|
||||
"task", InterInvokeSICSOBJ, KillSICSOBJ, pNew);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user