0N/A/*
1879N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. 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 *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#ifndef SHARE_VM_RUNTIME_TASK_HPP
1879N/A#define SHARE_VM_RUNTIME_TASK_HPP
1879N/A
1879N/A#include "utilities/top.hpp"
1879N/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
3863N/Aclass PeriodicTask: public CHeapObj<mtInternal> {
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:
4046N/A int _counter;
4046N/A const int _interval;
0N/A
0N/A static int _num_tasks;
0N/A static PeriodicTask* _tasks[PeriodicTask::max_tasks];
4046N/A static void real_time_tick(int 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 // Make the task active
4046N/A // For dynamic enrollment at the time T, the task will execute somewhere
4046N/A // between T and T + interval_time.
0N/A void enroll();
0N/A
0N/A // Make the task deactive
0N/A void disenroll();
0N/A
4046N/A void execute_if_pending(int delay_time) {
4046N/A // make sure we don't overflow
4046N/A jlong tmp = (jlong) _counter + (jlong) delay_time;
4046N/A
4046N/A if (tmp >= (jlong) _interval) {
0N/A _counter = 0;
0N/A task();
4046N/A } else {
4046N/A _counter += delay_time;
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.
4046N/A int 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.
4046N/A static int time_to_wait();
0N/A
0N/A // The task to perform at each period
0N/A virtual void task() = 0;
0N/A};
1879N/A
1879N/A#endif // SHARE_VM_RUNTIME_TASK_HPP