blob: 6d9095924d98e0c1556521e07a28f98ef41a00f5 [file] [log] [blame]
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_RUNTIME_NONJAVATHREAD_HPP
#define SHARE_RUNTIME_NONJAVATHREAD_HPP
#include "runtime/thread.hpp"
class NonJavaThread: public Thread {
friend class VMStructs;
NonJavaThread* volatile _next;
class List;
static List _the_list;
void add_to_the_list();
void remove_from_the_list();
protected:
virtual void pre_run();
virtual void post_run();
public:
NonJavaThread();
~NonJavaThread();
class Iterator;
};
// Provides iteration over the list of NonJavaThreads.
// List addition occurs in pre_run(), and removal occurs in post_run(),
// so that only live fully-initialized threads can be found in the list.
// Threads created after an iterator is constructed will not be visited
// by the iterator. The scope of an iterator is a critical section; there
// must be no safepoint checks in that scope.
class NonJavaThread::Iterator : public StackObj {
uint _protect_enter;
NonJavaThread* _current;
NONCOPYABLE(Iterator);
public:
Iterator();
~Iterator();
bool end() const { return _current == nullptr; }
NonJavaThread* current() const { return _current; }
void step();
};
// A base class for non-JavaThread subclasses with multiple
// uniquely named instances. NamedThreads also provide a common
// location to store GC information needed by GC threads
// and the VMThread.
class NamedThread: public NonJavaThread {
friend class VMStructs;
enum {
max_name_len = 64
};
private:
char* _name;
// log Thread being processed by oops_do
Thread* _processed_thread;
uint _gc_id; // The current GC id when a thread takes part in GC
public:
NamedThread();
~NamedThread();
// May only be called once per thread.
void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
virtual bool is_Named_thread() const { return true; }
virtual const char* name() const { return _name == nullptr ? "Unknown Thread" : _name; }
virtual const char* type_name() const { return "NamedThread"; }
Thread *processed_thread() { return _processed_thread; }
void set_processed_thread(Thread *thread) { _processed_thread = thread; }
virtual void print_on(outputStream* st) const;
void set_gc_id(uint gc_id) { _gc_id = gc_id; }
uint gc_id() { return _gc_id; }
};
// A single WatcherThread is used for simulating timer interrupts.
class WatcherThread: public NonJavaThread {
friend class VMStructs;
protected:
virtual void run();
private:
static WatcherThread* _watcher_thread;
static bool _run_all_tasks;
// volatile due to at least one lock-free read
volatile static bool _should_terminate;
public:
// Constructor
WatcherThread();
// No destruction allowed
~WatcherThread() {
guarantee(false, "WatcherThread deletion must fix the race with VM termination");
}
// Tester
bool is_Watcher_thread() const { return true; }
// Printing
const char* name() const { return "VM Periodic Task Thread"; }
const char* type_name() const { return "WatcherThread"; }
void print_on(outputStream* st) const;
void unpark();
// Returns the single instance of WatcherThread
static WatcherThread* watcher_thread() { return _watcher_thread; }
// Create and start the single instance of WatcherThread, or stop it on shutdown
static void start();
static void stop();
// Allow executing registered tasks once the VM is sufficiently
// initialized. Meanwhile only error reporting will be checked.
static void run_all_tasks();
private:
int sleep() const;
};
#endif // SHARE_RUNTIME_NONJAVATHREAD_HPP