8323612: IOVecWrapper should be changed to be TerminatingThreadLocal

Reviewed-by: bpb
This commit is contained in:
Alan Bateman 2024-01-17 10:56:17 +00:00
parent f2a4ed680b
commit b8dafa642e
2 changed files with 37 additions and 25 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, 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
@ -259,6 +259,7 @@ public final class IOUtil {
vec.clearRefs(j);
}
}
vec.release();
}
}
@ -470,6 +471,7 @@ public final class IOUtil {
vec.clearRefs(j);
}
}
vec.release();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, 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
@ -26,9 +26,7 @@
package sun.nio.ch;
import java.nio.ByteBuffer;
import jdk.internal.misc.CarrierThreadLocal;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.misc.TerminatingThreadLocal;
/**
* Manipulates a native array of iovec structs on Solaris:
@ -71,18 +69,20 @@ class IOVecWrapper {
// Address size in bytes
static final int addressSize;
private static class Deallocator implements Runnable {
private final AllocatedNativeObject obj;
Deallocator(AllocatedNativeObject obj) {
this.obj = obj;
}
public void run() {
obj.free();
}
}
// per carrier-thread IOVecWrapper
private static final CarrierThreadLocal<IOVecWrapper> cached = new CarrierThreadLocal<>();
private static final TerminatingThreadLocal<IOVecWrapper[]> IOV_CACHE = new TerminatingThreadLocal<>() {
@Override
protected IOVecWrapper[] initialValue() {
return new IOVecWrapper[1]; // one slot cache
}
@Override
protected void threadTerminated(IOVecWrapper[] cache) {
IOVecWrapper wrapper = cache[0];
if (wrapper != null) {
wrapper.vecArray.free();
}
}
};
private IOVecWrapper(int size) {
this.size = size;
@ -95,18 +95,28 @@ class IOVecWrapper {
}
static IOVecWrapper get(int size) {
IOVecWrapper wrapper = cached.get();
if (wrapper != null && wrapper.size < size) {
// not big enough; eagerly release memory
wrapper.vecArray.free();
wrapper = null;
IOVecWrapper[] cache = IOV_CACHE.get();
IOVecWrapper wrapper = cache[0];
if (wrapper != null) {
cache[0] = null;
if (wrapper.size < size) {
// not big enough; eagerly release memory
wrapper.vecArray.free();
wrapper = null;
}
}
return (wrapper != null) ? wrapper : new IOVecWrapper(size);
}
void release() {
IOVecWrapper[] cache = IOV_CACHE.get();
IOVecWrapper wrapper = cache[0];
if (wrapper == null) {
wrapper = new IOVecWrapper(size);
CleanerFactory.cleaner().register(wrapper, new Deallocator(wrapper.vecArray));
cached.set(wrapper);
cache[0] = this;
} else {
// slot already used
vecArray.free();
}
return wrapper;
}
void setBuffer(int i, ByteBuffer buf, int pos, int rem) {