mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8321594: NativeThreadSet should use placeholder for virtual threads
Reviewed-by: bpb
This commit is contained in:
parent
973bcdab81
commit
b8c0b2fd8c
3 changed files with 52 additions and 56 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -27,77 +27,89 @@ package sun.nio.ch;
|
||||||
|
|
||||||
// Special-purpose data structure for sets of native threads
|
// Special-purpose data structure for sets of native threads
|
||||||
|
|
||||||
|
|
||||||
class NativeThreadSet {
|
class NativeThreadSet {
|
||||||
|
private static final int OTHER_THREAD_INDEX = -99;
|
||||||
|
|
||||||
private long[] elts;
|
private final int initialCapacity;
|
||||||
private int used = 0;
|
private long[] threads; // array of thread handles, created lazily
|
||||||
|
private int used; // number of thread handles in threads array
|
||||||
|
private int otherThreads; // count of threads without a native thread handle
|
||||||
private boolean waitingToEmpty;
|
private boolean waitingToEmpty;
|
||||||
|
|
||||||
NativeThreadSet(int n) {
|
NativeThreadSet(int n) {
|
||||||
elts = new long[n];
|
initialCapacity = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the current native thread to this set, returning its index so that
|
* Adds the current thread handle to this set, returning an index so that
|
||||||
* it can efficiently be removed later.
|
* it can efficiently be removed later.
|
||||||
*/
|
*/
|
||||||
int add() {
|
int add() {
|
||||||
long th = NativeThread.currentNativeThread();
|
long th = NativeThread.current();
|
||||||
// 0 and -1 are treated as placeholders, not real thread handles
|
|
||||||
if (th == 0)
|
|
||||||
th = -1;
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
if (!NativeThread.isNativeThread(th)) {
|
||||||
|
otherThreads++;
|
||||||
|
return OTHER_THREAD_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add native thread handle to array, creating or growing array if needed
|
||||||
int start = 0;
|
int start = 0;
|
||||||
if (used >= elts.length) {
|
if (threads == null) {
|
||||||
int on = elts.length;
|
threads = new long[initialCapacity];
|
||||||
|
} else if (used >= threads.length) {
|
||||||
|
int on = threads.length;
|
||||||
int nn = on * 2;
|
int nn = on * 2;
|
||||||
long[] nelts = new long[nn];
|
long[] nthreads = new long[nn];
|
||||||
System.arraycopy(elts, 0, nelts, 0, on);
|
System.arraycopy(threads, 0, nthreads, 0, on);
|
||||||
elts = nelts;
|
threads = nthreads;
|
||||||
start = on;
|
start = on;
|
||||||
}
|
}
|
||||||
for (int i = start; i < elts.length; i++) {
|
for (int i = start; i < threads.length; i++) {
|
||||||
if (elts[i] == 0) {
|
if (threads[i] == 0) {
|
||||||
elts[i] = th;
|
threads[i] = th;
|
||||||
used++;
|
used++;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert false;
|
throw new InternalError();
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the thread at the give index.
|
* Removes the thread at the given index. A no-op if index is -1.
|
||||||
*/
|
*/
|
||||||
void remove(int i) {
|
void remove(int i) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
assert (elts[i] == NativeThread.currentNativeThread()) || (elts[i] == -1);
|
if (i >= 0) {
|
||||||
elts[i] = 0;
|
assert threads[i] == NativeThread.current();
|
||||||
|
threads[i] = 0;
|
||||||
used--;
|
used--;
|
||||||
if (used == 0 && waitingToEmpty)
|
} else if (i == OTHER_THREAD_INDEX) {
|
||||||
|
otherThreads--;
|
||||||
|
} else {
|
||||||
|
assert i == -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (used == 0 && otherThreads == 0 && waitingToEmpty) {
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Signals all threads in this set.
|
/**
|
||||||
//
|
* Signals all native threads in the thread set and wait for the thread set to empty.
|
||||||
|
*/
|
||||||
synchronized void signalAndWait() {
|
synchronized void signalAndWait() {
|
||||||
boolean interrupted = false;
|
boolean interrupted = false;
|
||||||
while (used > 0) {
|
while (used > 0 || otherThreads > 0) {
|
||||||
int u = used;
|
int u = used, i = 0;
|
||||||
int n = elts.length;
|
while (u > 0 && i < threads.length) {
|
||||||
for (int i = 0; i < n; i++) {
|
long th = threads[i];
|
||||||
long th = elts[i];
|
if (th != 0) {
|
||||||
if (th == 0)
|
|
||||||
continue;
|
|
||||||
if (th != -1)
|
|
||||||
NativeThread.signal(th);
|
NativeThread.signal(th);
|
||||||
if (--u == 0)
|
u--;
|
||||||
break;
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
waitingToEmpty = true;
|
waitingToEmpty = true;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -52,14 +52,6 @@ public class NativeThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the id of the current native thread if the platform can signal
|
|
||||||
* native threads, 0 if the platform can not signal native threads.
|
|
||||||
*/
|
|
||||||
static long currentNativeThread() {
|
|
||||||
return current0();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals the given native thread.
|
* Signals the given native thread.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -45,14 +45,6 @@ public class NativeThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the id of the current native thread if the platform can signal
|
|
||||||
* native threads, 0 if the platform can not signal native threads.
|
|
||||||
*/
|
|
||||||
static long currentNativeThread() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals the given native thread.
|
* Signals the given native thread.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue