Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8323612: IOVecWrapper should be changed to be TerminatingThreadLocal #17379

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/java.base/share/classes/sun/nio/ch/IOUtil.java
Original file line number Diff line number Diff line change
@@ -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 @@ static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
vec.clearRefs(j);
}
}
vec.release();
}
}

@@ -470,6 +471,7 @@ static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
vec.clearRefs(j);
}
}
vec.release();
}
}

56 changes: 33 additions & 23 deletions src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java
Original file line number Diff line number Diff line change
@@ -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;
// per carrier-thread IOVecWrapper
private static final TerminatingThreadLocal<IOVecWrapper[]> IOV_CACHE = new TerminatingThreadLocal<>() {
@Override
protected IOVecWrapper[] initialValue() {
return new IOVecWrapper[1]; // one slot cache
}
public void run() {
obj.free();
@Override
protected void threadTerminated(IOVecWrapper[] cache) {
IOVecWrapper wrapper = cache[0];
if (wrapper != null) {
wrapper.vecArray.free();
}
}
}

// per carrier-thread IOVecWrapper
private static final CarrierThreadLocal<IOVecWrapper> cached = new CarrierThreadLocal<>();
};

private IOVecWrapper(int size) {
this.size = size;
@@ -95,18 +95,28 @@ private IOVecWrapper(int size) {
}

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) {