📄 mal_factory.c
字号:
#line 280 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"#include "mal_config.h"#include "mal_factory.h"typedef struct { int id; /* unique plant number */ MalBlkPtr factory; MalStkPtr stk; /* private state */ int pc; /* where we are */ int inuse; /* able to handle it */ int next; /* next plant of same factory */ int policy; /* flags to control behavior */ str location; /* where the factoryMgr resides */ Client client; /* who called it */ MalBlkPtr caller; /* from routine */ MalStkPtr env; /* with the stack */ InstrPtr pci; /* with the instruction */} PlantRecord, *Plant;#define MAXPLANTS 256static PlantRecord plants[MAXPLANTS];static int lastPlant;static int plantId = 1;mal_export Plant newPlant(MalBlkPtr mb);intfactoryHasFreeSpace(){ return lastPlant <255;}intfindPlant(MalBlkPtr mb){ int i; for(i=0; i<lastPlant; i++) if( plants[i].factory == mb) return i; return -1;}strrunFactory(Client cntxt, MalBlkPtr mb, MalBlkPtr mbcaller, MalStkPtr stk, InstrPtr pci){ Plant pl=0; int firstcall= TRUE, i, k; InstrPtr psig = getInstrPtr(mb, 0); ValPtr lhs, rhs; char cmd; str msg;#ifdef DEBUG_MAL_FACTORY stream_printf(GDKout, "factoryMgr called\n");#endif /* the lookup can be largely avoided by handing out the index upon factory definition. todo Alternative is to move them to the front */ for(i=0; i< lastPlant; i++) if( plants[i].factory == mb){ if(i > 0 && i< lastPlant ){ PlantRecord prec= plants[i-1]; plants[i-1] = plants[i]; plants[i]= prec; i--; } pl= plants+i; firstcall= FALSE; break; } if (pl == 0) { /* compress the plant table*/ for(k=i=0;i<lastPlant; i++) if( plants[i].inuse) plants[k++]= plants[i]; lastPlant = k; /* initialize a new plant using the owner policy */ pl = newPlant(mb); if (pl == NULL) throw(MAL, "factory.new", "No factory space left"); } if (pl->location) throw(INVCRED, "factory.new", "No remote access allowed");#line 365 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx" /* remember context */ pl->client = cntxt; pl->caller = mbcaller; pl->env = stk; pl->pci = pci; pl->inuse = 1; /* inherit debugging */ cmd = stk->cmd; if( pl->stk) pl->stk->cmd= cmd; /* copy the calling arguments onto the stack of the factory */ i = psig->retc; for (k = pci->retc; i < pci->argc; i++, k++) { lhs = &pl->stk->stk[getArg(psig, k)]; /* variable arguments ? */ if (k == psig->argc - 1) k--; rhs = &pl->env->stk[getArg(pci, i)]; VALcopy(lhs, rhs); if( lhs->vtype == TYPE_bat ) BBPincref(lhs->val.br.id, TRUE); } if (mb->errors) throw(MAL, "factory.call", "Factory contains errors"); if (firstcall ) msg = runMAL(cntxt, mb, 1, 0, pl->stk, 0); else { if( cmd && cntxt->timer == 0) mdbStep(cntxt,mb,pl->stk,pl->pc); msg = reenterMAL(cntxt, mb, pl->pc, -1, pl->stk, 0, 0); } /* propagate change in debugging status */ if (cmd && pl->stk && pl->stk->cmd != cmd && cmd != 'x') for (; stk; stk = stk->up) stk->cmd = pl->stk->cmd; return msg;}#line 409 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"strcallFactory(Client cntxt, MalBlkPtr mb, ValPtr argv[], char flag){ Plant pl; InstrPtr psig = getInstrPtr(mb, 0); int i; ValPtr lhs,rhs; MalStkPtr stk; str ret; i= findPlant(mb); if( i< 0) { /* first call? prepare the factory */ pl = newPlant(mb); if (pl == NULL) throw(MAL, "factory.call", "No factory space left"); /* remember context, which does not exist. */ pl->client = cntxt; pl->caller = 0; pl->env = 0; pl->pci = 0; pl->inuse = 1; stk = pl->stk; /* initialize the stack */ stk->stktop= mb->vtop; stk->stksize= mb->vsize; stk->blk= mb; stk->up = 0; stk->cmd= flag; /* initialize the stack */ for(i= psig->argc; i< mb->vtop; i++) if( isConstant(mb,i) > 0 ){ lhs = &stk->stk[i]; rhs = &getVarConstant(mb,i); VALcopy2(lhs,rhs); } else { lhs = &stk->stk[i]; lhs->vtype = getVarGDKType(mb,i); } pl->stk= stk; } else { pl= plants+i;#line 454 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx" for (i = psig->retc; i < psig->argc; i++) { lhs = &pl->stk->stk[getArg(psig, i)]; if( lhs->vtype == TYPE_bat ) BBPdecref(lhs->val.br.id, TRUE); } } /* copy the calling arguments onto the stack of the factory */ i = psig->retc; for (i = psig->retc; i < psig->argc; i++) { lhs = &pl->stk->stk[getArg(psig, i)]; VALcopy(lhs, argv[i]); if( lhs->vtype == TYPE_bat ) BBPincref(lhs->val.br.id, TRUE); } if( flag && cntxt->timer == 0) mdbStep(cntxt,mb,pl->stk,pl->pc); ret= reenterMAL(cntxt, mb, pl->pc, -1, pl->stk, 0, 0); /* garbage collect the string arguments, these positions will simply be overwritten the next time. for (i = psig->retc; i < psig->argc; i++) { garbageElement(&pl->stk->stk[getArg(psig, i)]); } */ return ret;}#line 484 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"PlantnewPlant(MalBlkPtr mb){ Plant p, plim;#ifdef DEBUG_MAL_FACTORY stream_printf(GDKout, "newPlant called\n");#endif plim = plants + lastPlant; for (p = plants; p < plim && p->factory; p++) ; if (lastPlant == MAXPLANTS) return 0; if (p == plim) lastPlant++; p->factory = mb; p->id = plantId++; p->pc = 1; /* where we start */ p->stk = newGlobalStack(mb->vsize); p->stk->blk = mb; p->stk->keepAlive = TRUE; return p;}#line 515 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"intyieldResult(MalBlkPtr mb, InstrPtr p, int pc){ Plant pl, plim = plants + lastPlant; ValPtr lhs, rhs; int i; (void) p; (void) pc; for (pl = plants; pl < plim; pl++) if (pl->factory == mb ) { if( pl->env == NULL) return pl-plants; for (i = 0; i < p->retc; i++) {#ifdef DEBUG_MAL_FACTORY printf("lhs %d rhs %d\n", getArg(pl->pci, i), getArg(p, i));#endif rhs = &pl->stk->stk[getArg(p, i)]; lhs = &pl->env->stk[getArg(pl->pci, i)]; VALcopy(lhs, rhs); } return pl-plants; } return -1;}stryieldFactory(MalBlkPtr mb, InstrPtr p, int pc){ Plant pl; int i; i = yieldResult(mb, p, pc); if (i>=0) { pl = plants+i; pl->inuse = 0; pl->pc = pc + 1; pl->client = NULL; pl->caller = NULL; pl->pci = NULL; pl->env = NULL; return MAL_SUCCEED; } throw(MAL, "factory.yield", "No factory found");}#line 567 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"strshutdownFactory(MalBlkPtr mb){ Plant pl, plim;#ifdef DEBUG_MAL_FACTORY stream_printf(GDKout, "shutdownFactory called\n");#endif plim = plants + lastPlant; for (pl = plants; pl < plim; pl++) if (pl->factory == mb) { /* MSresetVariables(mb, pl->stk, 0);*/ /* freeStack(pl->stk); there may be a reference?*/ /* we are inside the body of the factory and about to return */ pl->factory = 0; pl->stk->keepAlive = FALSE; pl->stk=0; pl->pc = 0; pl->inuse = 0; pl->client = NULL; pl->caller = NULL; pl->pci = NULL; pl->env = NULL; pl->client = NULL; pl->caller = NULL; pl->env= NULL; pl->pci = NULL; } return MAL_SUCCEED;}strshutdownFactoryByName(Module m, str nme){ Plant pl, plim; InstrPtr p; Symbol s;#ifdef DEBUG_MAL_FACTORY stream_printf(GDKout, "shutdownFactory called\n");#endif plim = plants + lastPlant; for (pl = plants; pl < plim; pl++) if (pl->factory ) { MalStkPtr stk; p= getInstrPtr(pl->factory,0); if( strcmp(nme, getFunctionId(p)) != 0) continue; s = findSymbolInModule(m, getName(nme,strlen(nme)) ); if (s == NULL){ throw(MAL, "factory.remove", "Internal error, sql_cache entry '%s' missing", getName(nme, strlen(nme))); } stk = pl->stk; MSresetVariables(pl->factory, stk, 0); shutdownFactory(pl->factory); freeStack(stk); deleteSymbol(m,s); return MAL_SUCCEED; } return MAL_SUCCEED;}strfinishFactory(MalBlkPtr mb, InstrPtr pp, int pc){ (void) pp; (void) pc; return shutdownFactory(mb);}#line 641 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"#line 643 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_factory.mx"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -