int uthread_init(int quantum_usecs) { if (quantum_usecs <= 0) { std::cerr << INIT_ERR << std::endl; return FAILURE; } for (int i = 1; i< MAX_THREAD_NUM +1; i++) { gAvailableID.push(i); } gQuantum_usecs = quantum_usecs; gTotalQuantums = 0; Thread *mainThread = new Thread(0, ORANGE); gThreads[0] = mainThread; // initialize signal handler gAct.sa_handler = timerHandler; if (sigemptyset(&gAct.sa_mask)== FAILURE) { std::cerr << SIGEMPTY_ERR << strerror(EINVAL) << std::endl; exit(1); } gAct.sa_flags = 0; if (sigaction(SIGVTALRM, &gAct, NULL) == FAILURE) { std::cerr<< SIGACTION_ERR <<std::endl; exit(1); } initTimer(); gRunning = mainThread; mainThread->setState(RUNNING); switchThreads(RUNNING); // create sigset for blocking signals later on if (sigemptyset(&gSignalSet) == FAILURE) { std::cerr << SIGEMPTY_ERR << strerror(EINVAL) << std::endl; exit(1); } if (sigaddset(&gSignalSet,SIGVTALRM) == FAILURE) { std::cerr << SIGADD_ERR << strerror(EINVAL) << std::endl; exit(1); } return SUCCESS; }
int uthread_suspend(int tid) { blockTimer(); if(tid == 0) { std::cerr<< BLOCK_ERR_MAIN <<std::endl; resumeTimer(); return FAILURE; } if(gThreads.count(tid) == 0) { std::cerr << BLOCK_ERR << " Thread does not exist." << std::endl; resumeTimer(); return FAILURE; } Thread* tmp = gThreads[tid]; if(tmp->getState() == BLOCKED ) { // no effect resumeTimer(); return SUCCESS; } if(tmp->getState() == RUNNING ) { // make scheduling decision (move to next thread) switchThreads(BLOCKED); resumeTimer(); return SUCCESS; } if(tmp->getState() == READY ) { // move to gBlocked + update state in thread gReady.remove(tid); gBlocked[tid] = tmp; tmp->setState(BLOCKED); resumeTimer(); return SUCCESS; } std::cerr << BLOCK_ERR << std::endl; resumeTimer(); return FAILURE; }
/** * Calls switchThreads() with the threadId retrieved from get_next_thread() */ void switchNextThread() { sei(); switchThreads(get_next_thread()); cli(); }
int uthread_terminate(int tid) { blockTimer(); if(tid == 0)//if true: exits program { // terminate all threads: std::map<int, Thread*>::iterator threadIt; for (threadIt = gThreads.begin(); threadIt != gThreads.end(); ++threadIt) { Thread* tmp; switch(threadIt->second->getState() ) { case(READY) : gReady.remove(threadIt->second->getID() ); tmp = gThreads[threadIt->second->getID() ]; gThreads.erase(threadIt); delete tmp; break; case(RUNNING) : gThreads.erase(threadIt); // gRunning = NULL; break; case(BLOCKED) : gBlocked.erase(threadIt->second->getID() ); tmp = gThreads[threadIt->second->getID() ]; gThreads.erase(threadIt); delete tmp; break; default : break; } } delete gRunning; gRunning = NULL; resumeTimer(); exit(0); } if(gThreads.count(tid) == 0) //if true: thread doesn't exist { std::cerr<< TERMINATE_ERR << std::endl; resumeTimer(); return FAILURE; } if(gThreads[tid]->getState() == RUNNING)//if true: deletes thread + jumps to next thread { switchThreads(TERMINATED); } // if in ready or blocked: remove from lists (gReady/gBlocked + gThreads), and delete thread Thread* tmp = gThreads[tid]; if (tmp->getState() == READY ) { gReady.remove(tid); } if (tmp->getState() == BLOCKED) { gBlocked.erase(tid); } gThreads.erase(tid); gAvailableID.push(tid); delete tmp; resumeTimer(); return SUCCESS; }
void timerHandler(int sig) { switchThreads(READY); }