4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief Scheduler non-inline non-template implementation
31 \idea Multithreading support: To support multithreading, the
32 static member Scheduler::instance() must return a thread-local
33 value (that is Scheduler::instance() must allocate one Scheduler
34 instance per thread). Another possibility would be to distribute
35 the async load unto several threads (one scheduler for multiple
39 #include "Scheduler.hh"
40 //#include "Scheduler.ih"
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 bool terminate_ (false);
49 bool running_ (false);
52 prefix_ void senf::scheduler::terminate()
57 prefix_ void senf::scheduler::yield()
59 detail::FIFORunner::instance().yield();
62 prefix_ bool senf::scheduler::running()
67 prefix_ senf::ClockService::clock_type senf::scheduler::now()
69 return running() ? eventTime() : ClockService::now();
74 // We don't want try { } catch(...) { ... throw; } since that will make debugging more
75 // difficult: the stack backtrace for an unexpected exception would always end here.
76 struct SchedulerScopedInit
80 senf::scheduler::detail::FIFORunner::instance().startWatchdog();
81 senf::scheduler::detail::SignalDispatcher::instance().unblockSignals();
82 senf::scheduler::detail::TimerDispatcher::instance().enable();
86 ~SchedulerScopedInit()
88 senf::scheduler::detail::TimerDispatcher::instance().disable();
89 senf::scheduler::detail::SignalDispatcher::instance().blockSignals();
90 senf::scheduler::detail::FIFORunner::instance().stopWatchdog();
96 prefix_ void senf::scheduler::process()
98 SchedulerScopedInit initScheduler;
100 detail::TimerDispatcher::instance().reschedule();
101 while(! terminate_ && ! (detail::FdDispatcher::instance().empty() &&
102 detail::TimerDispatcher::instance().empty() &&
103 detail::FileDispatcher::instance().empty() &&
104 detail::IdleEventDispatcher::instance().empty()) ) {
105 detail::FdManager::instance().processOnce();
106 detail::FileDispatcher::instance().prepareRun();
107 detail::EventHookDispatcher::instance().prepareRun();
108 detail::TimerDispatcher::instance().prepareRun();
109 detail::IdleEventDispatcher::instance().prepareRun();
110 detail::FIFORunner::instance().run();
111 detail::TimerDispatcher::instance().reschedule();
115 prefix_ void senf::scheduler::restart()
117 detail::FdManager* fdm (&detail::FdManager::instance());
118 detail::FIFORunner* ffr (&detail::FIFORunner::instance());
119 detail::FdDispatcher* fdd (&detail::FdDispatcher::instance());
120 detail::TimerDispatcher* tdd (&detail::TimerDispatcher::instance());
121 detail::SignalDispatcher* sdd (&detail::SignalDispatcher::instance());
122 detail::FileDispatcher* fld (&detail::FileDispatcher::instance());
123 detail::IdleEventDispatcher* ied (&detail::IdleEventDispatcher::instance());
124 detail::EventHookDispatcher* eed (&detail::EventHookDispatcher::instance());
126 eed->~EventHookDispatcher();
127 ied->~IdleEventDispatcher();
128 fld->~FileDispatcher();
129 sdd->~SignalDispatcher();
130 tdd->~TimerDispatcher();
131 fdd->~FdDispatcher();
135 new (fdm) detail::FdManager();
136 new (ffr) detail::FIFORunner();
137 new (fdd) detail::FdDispatcher();
138 new (tdd) detail::TimerDispatcher();
139 new (sdd) detail::SignalDispatcher();
140 new (fld) detail::FileDispatcher();
141 new (ied) detail::IdleEventDispatcher();
142 new (eed) detail::EventHookDispatcher();
145 prefix_ bool senf::scheduler::empty()
147 return detail::FdDispatcher::instance().empty()
148 && detail::TimerDispatcher::instance().empty()
149 && detail::FileDispatcher::instance().empty()
150 && detail::SignalDispatcher::instance().empty()
151 && detail::IdleEventDispatcher::instance().empty()
152 && detail::EventHookDispatcher::instance().empty();
155 prefix_ void senf::scheduler::hiresTimers()
157 #ifdef HAVE_TIMERFD_CREATE
158 if (haveScalableHiresTimers())
159 detail::TimerDispatcher::instance().timerSource(
160 std::auto_ptr<detail::TimerSource>(new detail::TimerFDTimerSource()));
163 detail::TimerDispatcher::instance().timerSource(
164 std::auto_ptr<detail::TimerSource>(new detail::POSIXTimerSource()));
167 //-/////////////////////////////////////////////////////////////////////////////////////////////////
168 // senf::schedulerLogTimeSource
170 prefix_ senf::log::time_type senf::scheduler::LogTimeSource::operator()()
173 return senf::ClockService::in_nanoseconds( scheduler::now());
176 //-/////////////////////////////////////////////////////////////////////////////////////////////////
177 // senf::scheduler::BlockSignals
179 prefix_ senf::scheduler::BlockSignals::BlockSignals(bool initiallyBlocked)
182 ::sigfillset(&allSigs_);
183 if (initiallyBlocked)
187 prefix_ void senf::scheduler::BlockSignals::block()
191 ::sigprocmask(SIG_BLOCK, &allSigs_, &savedSigs_);
195 prefix_ void senf::scheduler::BlockSignals::unblock()
199 ::sigprocmask(SIG_SETMASK, &savedSigs_, 0);
203 //-/////////////////////////////////////////////////////////////////////////////////////////////////
210 // c-file-style: "senf"
211 // indent-tabs-mode: nil
212 // ispell-local-dictionary: "american"
213 // compile-command: "scons -u test"
214 // comment-column: 40