/* Note the return value for this is: * meABORT - there was a major failure (i.e. couldn't open the file) * meFALSE - user quit * meTRUE - succeded * this is used by the exit function which ignore the major failures */ static int regTestSave(meRegNode *sroot, int flags) { /* if its not a file or not changed or the changes are to be discarded * then nothing to do */ if(!(sroot->mode & meREGMODE_FROOT) || !(sroot->mode & meREGMODE_CHANGE) || (sroot->mode & meREGMODE_DISCARD)) return meTRUE ; if((flags & 0x01) && !(sroot->mode & meREGMODE_AUTO)) { meUByte prompt[meBUF_SIZE_MAX] ; int ret ; meStrcpy(prompt,(sroot->value != NULL) ? sroot->value:sroot->name) ; meStrcat(prompt,": Save registry") ; if((ret = mlyesno(prompt)) == meABORT) { ctrlg(meFALSE,1) ; return meFALSE ; } if(ret == meFALSE) return meTRUE ; } return regSave(sroot,NULL,sroot->mode) ; }
void fibre::yield() { SETBIT(flags, JMPBIT); // = JMPFROMROUTINE getExecAdd(retAdd); if(GETBIT(flags, JMPBIT) == JMPFROMROUTINE) { //I think it's safer for the routine to save it's own registers and stack data //it means that it can self unschedule regSave(this); jmpToAdd(mainRegs.retAdd); } }
void fibres_start() { coStData *curCoRo = mainRegs.next; regSave(&mainRegs); while(mainRegs.next != NULL) { CLRBIT(curCoRo->flags, JMPBIT); // = JMPFROMMAIN __asm__("MAINRET:"); regRestore(&mainRegs); //This might be a few too many checks if(GETBIT(curCoRo->flags, JMPBIT) == JMPFROMMAIN && !GETBIT(curCoRo->flags, FINISHED) && GETBIT(curCoRo->flags, SHEDULED)) { if(GETBIT(curCoRo->flags, CALLSTATUS) == CALL) { //We should onyl get in here once per routine, //there after we jmp back, not call back SETBIT(curCoRo->flags, CALLSTATUS); // = JMP //This is designed to replace to two calls below setStackAndCallToAdd(curCoRo->sp, curCoRo->retAdd); //Put us back into the right stack frame regRestore(&mainRegs); //Believe if or not, if we get here, the routine is finished SETBIT(curCoRo->flags, FINISHED); } else { //This is designed to replace to two calls below regRestoreAndJmpToYeild(curCoRo); } } if(GETBIT(curCoRo->flags, FINISHED) && curCoRo->mallocStack) { if(curCoRo->prev->next == curCoRo->next) { mainRegs.next = NULL; } else { curCoRo->prev->next = curCoRo->next; } } curCoRo = curCoRo->next; //printf("End loop\n"); } }
/* * saveRegistry * Save the registry to a file. * * Note the return value for this is: * meABORT - there was a major failure (i.e. couldn't open the file) * meFALSE - user quit * meTRUE - succeded * this is used by the exit function which ignore the major failures */ int saveRegistry (int f, int n) { meUByte filebuf [meBUF_SIZE_MAX]; meUByte rootbuf [128]; meRegNode *rnp; meInt mode ; if(n & 0x2) { rnp = root.child ; while (rnp != NULL) { if((f=regTestSave(rnp,n)) <= 0) return f ; rnp = rnp->next ; } return meTRUE ; } /* Get the input from the command line */ if(meGetString((meUByte *)"Save registry root",0, 0, rootbuf, 128) == meABORT) return meFALSE; /* Find the root */ if((rnp = regFind (&root, rootbuf)) == NULL) return mlwrite(MWCLEXEC|MWABORT,(meUByte *)"[Cannot find node %s]",rootbuf); mode = rnp->mode & ~meREGMODE_FROOT ; if((n & 4) == 0) { if(rnp->mode & meREGMODE_FROOT) meStrcpy(filebuf,rnp->value) ; else filebuf[0] = '\0' ; /* Get the filename */ if(meGetString((meUByte *)"Registry file",MLFILECASE|MLFILECASE, 0, filebuf, meBUF_SIZE_MAX) <= 0) return meFALSE ; mode |= meREGMODE_FROOT ; } return regSave(rnp,filebuf,mode) ; }
void web_appcall(void) { //writeLn("web_appcall\r\n"); coStData *curCoRo = &(uip_conn->appstate); //There is a global indicator to keep track of the current fibre currentFibre = curCoRo; regSave(&mainRegs); CLRBIT(curCoRo->flags, JMPBIT); // = JMPFROMMAIN __asm__("MAINRET:"); regRestore(&mainRegs); if(GETBIT(curCoRo->flags, JMPBIT) == JMPFROMMAIN && !GETBIT(curCoRo->flags, FINISHED) && GETBIT(curCoRo->flags, SHEDULED)) { if(GETBIT(curCoRo->flags, CALLSTATUS) == CALL) { //We should onyl get in here once per routine, //there after we jmp back, not call back SETBIT(curCoRo->flags, CALLSTATUS); // = JMP //This is designed to replace to two calls below setStackAndCallToAdd(curCoRo->sp, curCoRo->retAdd); //Put us back into the right stack frame regRestore(&mainRegs); //Believe if or not, if we get here, the routine is finished //SETBIT(curCoRo->flags, FINISHED); } else { //This is designed to replace to two calls below regRestoreAndJmpToYeild(curCoRo); } } }
void fibre::start(fibre *routineRegs, int *coRoSem) { int numOfRoutines = (*coRoSem); int routineId; //This is the sheduler, it needs lots of work //and carefully while((*coRoSem)) { for(routineId = 0; routineId < numOfRoutines; routineId ++) { printf("Begin loop\n"); CLRBIT(routineRegs[routineId].flags, JMPBIT); // = JMPFROMMAIN regSave(&mainRegs); getExecAdd(mainRegs.retAdd); regRestore(&mainRegs); //This might be a few too many checks if(GETBIT(routineRegs[routineId].flags, JMPBIT) == JMPFROMMAIN && !GETBIT(routineRegs[routineId].flags, FINISHED) && GETBIT(routineRegs[routineId].flags, SHEDULED)) { //This is an interesting call, that sets the objects reference to it's //fibre, this is updated dynamically all the time before each call routineRegs[routineId].obj->rt = &(routineRegs[routineId]); if(GETBIT(routineRegs[routineId].flags, CALLSTATUS) == CALL) { //We should onyl get in here once per routine, //there after we jmp back, not call back SETBIT(routineRegs[routineId].flags, CALLSTATUS); // = JMP //copy a pointer to the specific routine's reg data structure //onto it's stack so it's passed in as an argument routineRegs[routineId].SP -= sizeof(fibre *); *((fibre **)routineRegs[routineId].SP) = &(routineRegs[routineId]); //This is designed to replace to two calls below setStackAndCallToAdd(routineRegs[routineId].SP, routineRegs[routineId].retAdd); /* //point the stack to the new data setStack(routineRegs[routineId].SP); //call our function callToAdd(routineRegs[routineId].retAdd); */ } else { //This is designed to replace to two calls below regRestoreAndJmpToAdd(&routineRegs[routineId]); /* regRestore(&routineRegs[routineId]); jmpToAdd(routineRegs[routineId].retAdd); */ } } if(GETBIT(routineRegs[routineId].flags, FINISHED) && routineRegs[routineId].mallocStack) { //now that our routine is finished, get rid of it's stack free(routineRegs[routineId].mallocStack); routineRegs[routineId].mallocStack = NULL; (*coRoSem) --; } printf("End loop\n"); } } }