//state determines to which list/state gRunning will be pushed to. void switchThreads(State state) { gTotalQuantums++; if(gReady.empty() ) // either main thread is the only thread and it is running. // or other thread is running and main must be in ready list. { gRunning->increaseQuantum(); } else { Thread* next = gReady.pop(); int retVal = 0; switch(state) { case READY : gReady.push(gRunning); gRunning->setState(READY); retVal = sigsetjmp(*(gRunning->getThreadState() ),1); break; case BLOCKED : gRunning->setState(BLOCKED); gBlocked[gRunning->getID()] = gRunning; retVal = sigsetjmp(*(gRunning->getThreadState() ),1); break; case TERMINATED : gThreads.erase(gRunning->getID() ); gAvailableID.push(gRunning->getID() ); delete gRunning; retVal = 0; break; default : break; } if (retVal == 0) { gRunning = next; next->setState(RUNNING); gRunning->increaseQuantum(); siglongjmp(*(gRunning->getThreadState() ),1); } } if (setitimer(ITIMER_VIRTUAL, &gTimer, NULL) == FAILURE) { int errTmp = errno; std::cerr<< SETITIMER_ERR << strerror(errTmp) << std::endl; exit(1); } }
int uthread_spawn(void (*f)(void), Priority pr) { blockTimer(); int tid = gAvailableID.top(); if (tid < MAX_THREAD_NUM) { Thread *newThread = new Thread(tid, f, pr); gThreads[tid] = newThread; gAvailableID.pop(); gReady.push(newThread); resumeTimer(); return tid; } std::cerr<< SPAWN_ERR << std::endl; resumeTimer(); return FAILURE; }
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; }
int uthread_resume(int tid) { blockTimer(); if(gThreads.count(tid) == 0) // thread does not exist -- error { std::cerr << RESUME_ERR << std::endl; resumeTimer(); return FAILURE; } Thread* tmp = gThreads[tid]; if (tmp->getState() == READY || tmp->getState() == RUNNING ) //no effect { resumeTimer(); return SUCCESS; } // otherwise the thread should be in gBlocked (assuming no bugs...) gBlocked.erase(tid); gReady.push(tmp); tmp->setState(READY); resumeTimer(); return SUCCESS; }
int main( int argc, char** argv ) { cout << "\n Double link list\n"; DoubleLink<int> dblVec; dblVec.push( 3 ); dblVec.push( 1 ); dblVec.push( 10 ); dblVec.push( 15 ); dblVec.push( 8 ); dblVec.display(); dblVec.pop(); dblVec.display(); cout << "\n Stack list\n"; Stack<int> stack; stack.push( 3 ); stack.push( 1 ); stack.push( 10 ); stack.push( 15 ); stack.push( 8 ); stack.display(); stack.pop(); stack.display(); // cout << stack.find( 10 ) << endl; cout << "\n Queue list\n"; Queue<int> queue; queue.push( 3 ); queue.push( 1 ); queue.push( 10 ); queue.push( 15 ); queue.push( 8 ); queue.display(); queue.pop(); queue.display(); // cout << queue.find( 10 ) << endl; cout << "\n Circle list\n"; CircleLink<int> circle; circle.push( 3 ); circle.push( 1 ); circle.push( 10 ); circle.push( 15 ); circle.push( 8 ); circle.display(); circle.pop(); circle.display(); // cout << circle.find( 10 ) << endl; cout << "\n Sorted list\n"; SortedList<int> sort; sort.push( 3 ); sort.push( 1 ); sort.push( 10 ); sort.push( 15 ); sort.push( 8 ); sort.display(); sort.pop(); sort.display(); // cout << sort.find( 10 ) << endl; cout << "\nPriority list\n"; PriorityList<int> plist; plist.push( 3 ); plist.push( 1 ); plist.push( 10 ); plist.push( 15 ); plist.push( 8 ); plist.display(); plist.pop(); plist.display(); cout << plist.find( 10 ) << endl; plist.display(); }
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; }