2020-11-17 15:53:40 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2020 The Netty Project
|
|
|
|
*
|
|
|
|
* The Netty Project licenses this file to you under the Apache License,
|
|
|
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
|
|
* with the License. You may obtain a copy of the License at:
|
|
|
|
*
|
|
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*/
|
|
|
|
package io.netty.buffer.api.memseg;
|
|
|
|
|
2021-05-20 18:57:31 +02:00
|
|
|
import io.netty.buffer.api.internal.Statics;
|
2020-11-17 15:53:40 +01:00
|
|
|
import jdk.incubator.foreign.MemorySegment;
|
2021-04-07 14:28:05 +02:00
|
|
|
import jdk.incubator.foreign.ResourceScope;
|
2020-11-17 15:53:40 +01:00
|
|
|
|
2021-04-07 14:28:05 +02:00
|
|
|
import java.lang.ref.Cleaner;
|
2020-11-17 15:53:40 +01:00
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
2021-04-07 17:17:35 +02:00
|
|
|
import java.util.function.Function;
|
2020-11-17 15:53:40 +01:00
|
|
|
|
2021-04-07 16:19:35 +02:00
|
|
|
import static jdk.incubator.foreign.ResourceScope.newSharedScope;
|
|
|
|
|
2020-11-17 15:53:40 +01:00
|
|
|
public class NativeMemorySegmentManager extends AbstractMemorySegmentManager {
|
|
|
|
private static final ConcurrentHashMap<Long, Runnable> CLEANUP_ACTIONS = new ConcurrentHashMap<>();
|
2021-04-07 17:17:35 +02:00
|
|
|
private static final Function<Long, Runnable> CLEANUP_ACTION_MAKER = s -> new ReduceNativeMemoryUsage(s);
|
2020-11-17 15:53:40 +01:00
|
|
|
|
|
|
|
static Runnable getCleanupAction(long size) {
|
2021-04-07 17:17:35 +02:00
|
|
|
return CLEANUP_ACTIONS.computeIfAbsent(size, CLEANUP_ACTION_MAKER);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final class ReduceNativeMemoryUsage implements Runnable {
|
|
|
|
private final long size;
|
|
|
|
|
|
|
|
private ReduceNativeMemoryUsage(long size) {
|
|
|
|
this.size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2021-05-20 18:57:31 +02:00
|
|
|
Statics.MEM_USAGE_NATIVE.add(-size);
|
2021-04-07 17:17:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "ReduceNativeMemoryUsage(by " + size + " bytes)";
|
|
|
|
}
|
2020-11-17 15:53:40 +01:00
|
|
|
}
|
|
|
|
|
2021-05-11 11:24:06 +02:00
|
|
|
@Override
|
|
|
|
public boolean isNative() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-11-17 15:53:40 +01:00
|
|
|
@Override
|
2021-04-07 14:28:05 +02:00
|
|
|
protected MemorySegment createSegment(long size, Cleaner cleaner) {
|
2021-04-07 16:19:35 +02:00
|
|
|
final ResourceScope scope = cleaner == null ? newSharedScope() : newSharedScope(cleaner);
|
2021-04-26 17:08:40 +02:00
|
|
|
scope.addCloseAction(getCleanupAction(size));
|
2021-04-07 14:28:05 +02:00
|
|
|
var segment = MemorySegment.allocateNative(size, scope);
|
2021-05-20 18:57:31 +02:00
|
|
|
Statics.MEM_USAGE_NATIVE.add(size);
|
2020-11-17 15:53:40 +01:00
|
|
|
return segment;
|
|
|
|
}
|
|
|
|
}
|