task.hpp revision 0
0N/A/*
0N/A * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0N/A * CA 95054 USA or visit www.sun.com if you need additional information or
0N/A * have any questions.
0N/A *
0N/A */
0N/A
0N/A// A PeriodicTask has the sole purpose of executing its task
0N/A// function with regular intervals.
0N/A// Usage:
0N/A// PeriodicTask pf(10);
0N/A// pf.enroll();
0N/A// ...
0N/A// pf.disenroll();
0N/A
0N/Aclass PeriodicTask: public CHeapObj {
0N/A public:
0N/A // Useful constants.
0N/A // The interval constants are used to ensure the declared interval
0N/A // is appropriate; it must be between min_interval and max_interval,
0N/A // and have a granularity of interval_gran (all in millis).
0N/A enum { max_tasks = 10, // Max number of periodic tasks in system
0N/A interval_gran = 10,
0N/A min_interval = 10,
0N/A max_interval = 10000 };
0N/A
0N/A static int num_tasks() { return _num_tasks; }
0N/A
0N/A private:
0N/A size_t _counter;
0N/A const size_t _interval;
0N/A
0N/A static int _num_tasks;
0N/A static PeriodicTask* _tasks[PeriodicTask::max_tasks];
0N/A static void real_time_tick(size_t delay_time);
0N/A
0N/A#ifndef PRODUCT
0N/A static elapsedTimer _timer; // measures time between ticks
0N/A static int _ticks; // total number of ticks
0N/A static int _intervalHistogram[max_interval]; // to check spacing of timer interrupts
0N/A public:
0N/A static void print_intervals();
0N/A#endif
0N/A // Only the WatcherThread can cause us to execute PeriodicTasks
0N/A friend class WatcherThread;
0N/A public:
0N/A PeriodicTask(size_t interval_time); // interval is in milliseconds of elapsed time
0N/A ~PeriodicTask();
0N/A
0N/A // Tells whether is enrolled
0N/A bool is_enrolled() const;
0N/A
0N/A // Make the task active
0N/A // NOTE: this may only be called before the WatcherThread has been started
0N/A void enroll();
0N/A
0N/A // Make the task deactive
0N/A // NOTE: this may only be called either while the WatcherThread is
0N/A // inactive or by a task from within its task() method. One-shot or
0N/A // several-shot tasks may be implemented this way.
0N/A void disenroll();
0N/A
0N/A void execute_if_pending(size_t delay_time) {
0N/A _counter += delay_time;
0N/A if (_counter >= _interval) {
0N/A _counter = 0;
0N/A task();
0N/A }
0N/A }
0N/A
0N/A // Returns how long (time in milliseconds) before the next time we should
0N/A // execute this task.
0N/A size_t time_to_next_interval() const {
0N/A assert(_interval > _counter, "task counter greater than interval?");
0N/A return _interval - _counter;
0N/A }
0N/A
0N/A // Calculate when the next periodic task will fire.
0N/A // Called by the WatcherThread's run method.
0N/A // This assumes that periodic tasks aren't entering the system
0N/A // dynamically, except for during startup.
0N/A static size_t time_to_wait() {
0N/A if (_num_tasks == 0) {
0N/A // Don't wait any more; shut down the thread since we don't
0N/A // currently support dynamic enrollment.
0N/A return 0;
0N/A }
0N/A
0N/A size_t delay = _tasks[0]->time_to_next_interval();
0N/A for (int index = 1; index < _num_tasks; index++) {
0N/A delay = MIN2(delay, _tasks[index]->time_to_next_interval());
0N/A }
0N/A return delay;
0N/A }
0N/A
0N/A // The task to perform at each period
0N/A virtual void task() = 0;
0N/A};
0N/A
0N/Aclass TimeMillisUpdateTask : public PeriodicTask {
0N/A private:
0N/A static TimeMillisUpdateTask* _task;
0N/A public:
0N/A TimeMillisUpdateTask(int interval) : PeriodicTask(interval) {}
0N/A void task();
0N/A static void engage();
0N/A static void disengage();
0N/A};