package org.kne.opencl64;

import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;

import club.doki7.opencl.CLConstants;

public class OpenCLSVMMemory {
	
	private static final Cleaner clr=Cleaner.create();
	
	private OpenCLContext context;

	private MemorySegment svmMemory;

	public OpenCLSVMMemory(OpenCLContext context,OpenCLMemoryRWFlag rwflag,boolean finebuffer,long size,int aligment) {
		this.context=context;
		svmMemory= OpenCLPlatform.opencl.SVMAlloc(context.getCl_context(), rwflag.flagValue|(finebuffer?CLConstants. MEM_SVM_FINE_GRAIN_BUFFER:0), size, aligment);
		releaser=new OpenCLSVMMemoryReleaser(svmMemory);
		clr.register(this, releaser);
	}
	public OpenCLSVMMemory(OpenCLContext context,OpenCLMemoryRWFlag rwflag,boolean finebuffer,long size) {
		this(context,rwflag,finebuffer,size,0);
	}
		
	public MemorySegment getSvmMemory() {
		return svmMemory;
	}


	private OpenCLSVMMemoryReleaser releaser;
	
	public void close() {
		releaser.run();
	}
	
	public boolean isClosed() {
		return releaser.isReleased();
	}
	
	private class OpenCLSVMMemoryReleaser extends Releaser<MemorySegment>{

		public OpenCLSVMMemoryReleaser(MemorySegment resource) {
			super(resource);
		}

		@Override
		protected void release(MemorySegment resource) {
			OpenCLPlatform.opencl.SVMFree(context.getCl_context(), svmMemory);
		}
		
	}
}
