void Scheduler::schedule(uint64 maxTics) { bool handleTopEvent; Event nextEvent; while(1) { do { // List access must be atomic setAtomic(); if (eventQueue.empty() || !eventQueue.top().isExpired(timeTics)) { handleTopEvent = false; } else { if (eventQueue.top().isActive()) handleTopEvent = true; else handleTopEvent = false; nextEvent = eventQueue.top(); eventQueue.pop(); } unsetAtomic(); if (handleTopEvent) handleEvent(nextEvent); } while (handleTopEvent); // if there was a request for deleting tasks, we gonna do that now handleKillRequests(); // set the time of the next event, if one setNextEvent(); while (tics == timeTics){}; // PORTA ^= 0x01; timeTics = tics; // static uint32 i=0; // if (i%1000 == 0) // PORTA ^= 0x01; } }
void Scheduler::schedule(uint32 time) { fd_set readfds, writefds, errorfds; int retval; int maxfd; std::map<int, TaskListSelectItem>::iterator TLSIterator; timev wait; uint32 maxTics = time*HZ; // if this is the first time, we get here, initialize the time if (nextEvent.infinite()) { startTime.set2now(); nextEvent.set2now(); } while((!maxTics) || (timeTics < maxTics)) { setNowTics(); Event event; while ((!EventList.empty()) && (event = EventList.top()).isExpired(timeTics)) { EventList.pop(); #ifndef WITH_BADGUY_TEST handleEvent(event); #else timev now; now.set2now(); handleEvent(event); timev execTime; execTime.set2now(); timev diff(20); // 20msec execTime -= now; if (execTime > diff) std::cerr<<"Scheduler: slow task, difference is " <<execTime.toString()<<"\n"; #endif } setNextEvent(); while (!nextEvent.expired()) { // wait until a descriptor is set, the time is up FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&errorfds); maxfd = 0; for (TLSIterator=TaskListSelectRead.begin(); TLSIterator!=TaskListSelectRead.end(); ++TLSIterator){ maxfd = ( (TLSIterator->first > maxfd) ? TLSIterator->first : maxfd); FD_SET(TLSIterator->first, &readfds); } for (TLSIterator=TaskListSelectWrite.begin(); TLSIterator!=TaskListSelectWrite.end(); ++TLSIterator){ maxfd = ( (TLSIterator->first > maxfd) ? TLSIterator->first : maxfd); FD_SET(TLSIterator->first, &writefds); } for (TLSIterator=TaskListSelectError.begin(); TLSIterator!=TaskListSelectError.end(); ++TLSIterator){ maxfd = ( (TLSIterator->first > maxfd) ? TLSIterator->first : maxfd); FD_SET(TLSIterator->first, &errorfds); } wait = nextEvent.expireTime(); retval = select(maxfd+1, &readfds, &writefds, &errorfds, &wait); // if this is not a timeout find the connected ask and call it. if (retval > 0) { setNowTics(); for (TLSIterator=TaskListSelectRead.begin(); TLSIterator!=TaskListSelectRead.end(); ++TLSIterator) if (FD_ISSET(TLSIterator->first, &readfds)) { Event event(TLSIterator->second.eventID, timeTics, TLSIterator->second.task); handleEvent(event); } for (TLSIterator=TaskListSelectWrite.begin(); TLSIterator!=TaskListSelectWrite.end(); ++TLSIterator) if (FD_ISSET(TLSIterator->first, &writefds)) { Event event(TLSIterator->second.eventID, timeTics, TLSIterator->second.task); handleEvent(event); } for (TLSIterator=TaskListSelectError.begin(); TLSIterator!=TaskListSelectError.end(); ++TLSIterator) if (FD_ISSET(TLSIterator->first, &errorfds)) { Event event(TLSIterator->second.eventID, timeTics, TLSIterator->second.task); handleEvent(event); } // look at the next timeout setNextEvent(); } else if (retval == -1) perror("scheduler: select failed"); } } }