diff --git a/.gitignore b/.gitignore index eae1343b..323c4fb4 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ dependency-reduced-pom.xml service-dist/ .*.html testlog/ +.DS_Store + diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/VolatileMemAllocator.java b/mnemonic-core/src/main/java/org/apache/mnemonic/VolatileMemAllocator.java index ef13a072..e7667edc 100644 --- a/mnemonic-core/src/main/java/org/apache/mnemonic/VolatileMemAllocator.java +++ b/mnemonic-core/src/main/java/org/apache/mnemonic/VolatileMemAllocator.java @@ -29,11 +29,12 @@ * * */ -public class VolatileMemAllocator extends CommonAllocator { +public class VolatileMemAllocator extends RestorableAllocator { private boolean m_activegc = true; private long m_gctimeout = 100; private long m_nid = -1; + private long[][] m_ttable; private VolatileMemoryAllocatorService m_vmasvc = null; /** @@ -275,4 +276,229 @@ public MemBufferHolder createBuffer(long size, boolean aut return ret; } + /** + * retrieve a memory buffer from its backed memory allocator. + * + * @param phandler + * specify the handler of memory buffer to retrieve + * + * @param autoreclaim + * specify whether this retrieved memory buffer can be reclaimed + * automatically or not + * + * @return a holder contains the retrieved memory buffer + */ + @Override + public MemBufferHolder retrieveBuffer(long phandler, boolean autoreclaim) { + MemBufferHolder ret = null; + ByteBuffer bb = m_vmasvc.retrieveByteBuffer(m_nid, getEffectiveAddress(phandler)); + if (null != bb) { + ret = new MemBufferHolder(this, bb); + if (autoreclaim) { + m_bufcollector.register(ret); + } + } + return ret; + } + + /** + * retrieve a memory chunk from its backed memory allocator. + * + * @param phandler + * specify the handler of memory chunk to retrieve + * + * @param autoreclaim + * specify whether this retrieved memory chunk can be reclaimed + * automatically or not + * + * @return a holder contains the retrieved memory chunk + */ + @Override + public MemChunkHolder retrieveChunk(long phandler, boolean autoreclaim) { + MemChunkHolder ret = null; + long eaddr = getEffectiveAddress(phandler); + long sz = m_vmasvc.retrieveSize(m_nid, eaddr); + if (sz > 0L) { + ret = new MemChunkHolder(this, eaddr, sz); + if (autoreclaim) { + m_chunkcollector.register(ret); + } + } + return ret; + } + + /** + * get the handler from a memory buffer holder. + * + * @param mbuf + * specify the memory buffer holder + * + * @return a handler that could be used to retrieve its memory buffer + */ + @Override + public long getBufferHandler(MemBufferHolder mbuf) { + return getPortableAddress(m_vmasvc.getByteBufferHandler(m_nid, mbuf.get())); + } + + /** + * get the handler from a memory chunk holder. + * + * @param mchunk + * specify the memory chunk holder + * + * @return a handler that could be used to retrieve its memory chunk + */ + @Override + public long getChunkHandler(MemChunkHolder mchunk) { + return getPortableAddress(mchunk.get()); + } + + /** + * determine whether this allocator supports to store non-volatile handler or + * not. (it is a placeholder) + * + * @return true if there is + */ + @Override + public boolean hasDurableHandlerStore() { + return true; + } + + /** + * determine whether the allocator supports transaction feature or not + * + * @return true if supported + */ + @Override + public boolean supportTransaction() { + return false; + } + + /** + * start a application level transaction on this allocator. (it is a place + * holder) + * + */ + @Override + public void beginTransaction() { + throw new UnsupportedOperationException("Transaction Unsupported."); + } + + /** + * end a application level transaction on this allocator. (it is a place + * holder) + * + */ + @Override + public void endTransaction() { + throw new UnsupportedOperationException("Transaction Unsupported."); + } + + /** + * determine whether the allocator does atomic operations on memory pool + * + * @return true if it does + * + */ + @Override + public boolean isAtomicOperation() { + return false; + } + + /** + * set a handler on key. + * + * @param key + * the key to set its value + * + * @param handler + * the handler + */ + @Override + public void setHandler(long key, long handler) { + m_vmasvc.setHandler(m_nid, key, handler); + } + + /** + * get a handler value. + * + * @param key + * the key to set its value + * + * @return the value of handler + */ + @Override + public long getHandler(long key) { + return m_vmasvc.getHandler(m_nid, key); + } + + /** + * return the capacity of non-volatile handler store. + * + * @return the capacity of handler store + * + */ + public long handlerCapacity() { + return m_vmasvc.handlerCapacity(m_nid); + } + + /** + * translate the portable address + * + * @param addr + * the address to be translated + * + * @return the portable address + */ + @Override + public long getPortableAddress(long addr) { + int i; + for (i = 0; i < m_ttable.length; ++i) { + if (addr >= m_ttable[i][2] && addr < m_ttable[i][1] + m_ttable[i][2]) { + return addr - m_ttable[i][2]; + } + } + throw new AddressTranslateError("Portable Address Translate Error"); + } + + /** + * translate the effective address + * + * @param addr + * the address to be translated + * + * @return the effective address + */ + @Override + public long getEffectiveAddress(long addr) { + int i; + for (i = 0; i < m_ttable.length; ++i) { + if (addr >= m_ttable[i][0] && addr < m_ttable[i][1]) { + return addr + m_ttable[i][2]; + } + } + throw new AddressTranslateError("Effective Address Translate Error"); + } + + /** + * get the address translate table + * + * @return the translate table + */ + @Override + public long[][] getTranslateTable() { + return m_ttable; + } + + /** + * set address translate table + * + * @param tbl + * specify a translate table + */ + @Override + public void setTranslateTable(long[][] tbl) { + m_ttable = tbl; + } + } diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java b/mnemonic-core/src/main/java/org/apache/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java index dac017d0..b44dad8d 100644 --- a/mnemonic-core/src/main/java/org/apache/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java +++ b/mnemonic-core/src/main/java/org/apache/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java @@ -21,6 +21,96 @@ public interface VolatileMemoryAllocatorService { + + /** + * retrieve a bytebuffer from its handler + * + * @param id + * the identifier of backed memory pool + * + * @param handler + * the handler of a nonvolatile bytebuffer + * + * @return the nonvolatile bytebuffer + * + */ + ByteBuffer retrieveByteBuffer(long id, long handler); + + /** + * retrieve the size of a nonvolatile memory object + * + * @param id + * the identifier of backed memory pool + * + * @param handler + * the handler of a nonvolatile object + * + * @return the size of nonvolatile object + * + */ + long retrieveSize(long id, long handler); + + /** + * get the handler of a nonvolatile bytebuffer + * + * @param id + * the identifier of backed memory pool + * + * @param buf + * the nonvolatile bytebuffer + * + * @return the handler of this specified nonvolatile bytebuffer + * + */ + long getByteBufferHandler(long id, ByteBuffer buf); + + /** + * set a handler to a key. + * + * @param id + * the identifier of backed memory pool + * + * @param key + * the key to set this handler + * + * @param handler + * the handler + */ + void setHandler(long id, long key, long handler); + + /** + * get a handler from specified key. + * + * @param id + * the identifier of backed memory pool + * + * @param key + * the key to get its handler + * + * @return the handler of the specified key + */ + long getHandler(long id, long key); + + /** + * return the number of available keys to use. + * + * @param id + * the identifier of backed memory pool + * + * @return the number of keys + */ + long handlerCapacity(long id); + + /** + * return the base address of this persistent memory pool. + * + * @param id + * the identifier of backed memory pool + * + * @return the base address of this pmem pool + */ + long getBaseAddress(long id); + /** * Provide the service identifier for this allocator * diff --git a/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/java/org/apache/mnemonic/service/allocatorservice/internal/VMemServiceImpl.java b/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/java/org/apache/mnemonic/service/allocatorservice/internal/VMemServiceImpl.java index 1717bf15..93188f7b 100644 --- a/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/java/org/apache/mnemonic/service/allocatorservice/internal/VMemServiceImpl.java +++ b/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/java/org/apache/mnemonic/service/allocatorservice/internal/VMemServiceImpl.java @@ -93,6 +93,41 @@ public void destroyByteBuffer(long id, ByteBuffer bytebuf) { ndestroyByteBuffer(id, bytebuf); } + @Override + public ByteBuffer retrieveByteBuffer(long id, long handler) { + return nretrieveByteBuffer(id, handler); + } + + @Override + public long retrieveSize(long id, long handler) { + return nretrieveSize(id, handler); + } + + @Override + public long getByteBufferHandler(long id, ByteBuffer buf) { + return ngetByteBufferHandler(id, buf); + } + + @Override + public void setHandler(long id, long key, long handler) { + nsetHandler(id, key, handler); + } + + @Override + public long getHandler(long id, long key) { + return ngetHandler(id, key); + } + + @Override + public long handlerCapacity(long id) { + return nhandlerCapacity(id); + } + + @Override + public long getBaseAddress(long id) { + return ngetBaseAddress(id); + } + protected native long ninit(long capacity, String uri, boolean isnew); protected native void nclose(long id); @@ -113,4 +148,18 @@ public void destroyByteBuffer(long id, ByteBuffer bytebuf) { protected native void ndestroyByteBuffer(long id, ByteBuffer bytebuf); + protected native ByteBuffer nretrieveByteBuffer(long id, long handler); + + protected native long nretrieveSize(long id, long handler); + + protected native long ngetByteBufferHandler(long id, ByteBuffer buf); + + protected native void nsetHandler(long id, long key, long handler); + + protected native long ngetHandler(long id, long key); + + protected native long nhandlerCapacity(long id); + + protected native long ngetBaseAddress(long id); + } diff --git a/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/native/org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl.c b/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/native/org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl.c index 450edd52..c60b15ed 100644 --- a/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/native/org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl.c +++ b/mnemonic-memory-services/mnemonic-nvml-vmem-service/src/main/native/org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl.c @@ -99,6 +99,38 @@ jobject JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemS return ret; } +JNIEXPORT +jobject JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_nretrieveByteBuffer( + JNIEnv *env, jobject this, jlong id, jlong e_addr, jlong size) { + jobject ret = NULL; + void* p = addr_from_java(e_addr); + ret = NULL != p ? (*env)->NewDirectByteBuffer(env, p, size) : NULL; + return ret; +} + +JNIEXPORT +jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_nretrieveSize(JNIEnv *env, + jobject this, jlong id, jlong e_addr, jlong size) { + jlong ret = 0L; + void* p = addr_from_java(e_addr); + ret = NULL != p ? (*env)->NewDirectByteBuffer(env, p, size) : NULL; + return ret; +} + +JNIEXPORT +jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_ngetByteBufferHandler( + JNIEnv *env, jobject this, jlong id, jobject bytebuf) { +// fprintf(stderr, "ngetByteBufferAddress Get Called %X, %X\n", env, bytebuf); + jlong ret = 0L; + if (NULL != bytebuf) { + void* nativebuf = (*env)->GetDirectBufferAddress(env, bytebuf); +// fprintf(stderr, "ngetByteBufferAddress Get Native address %X\n", nativebuf); + ret = addr_to_java(nativebuf); + } +// fprintf(stderr, "ngetByteBufferAddress returned address %016lx\n", ret); + return ret; +} + JNIEXPORT jobject JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_nresizeByteBuffer( JNIEnv *env, jobject this, jlong id, jobject bytebuf, jlong size) { @@ -133,6 +165,37 @@ void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServ pthread_rwlock_unlock(&g_vmem_rwlock); } + +JNIEXPORT +void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_nsetHandler( + JNIEnv *env, jobject this, jlong id, jlong key, jlong value) +{ + throw(env, "setkey()/getkey() temporarily not suppoted"); +} + +JNIEXPORT +jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_ngetHandler(JNIEnv *env, + jobject this, jlong id, jlong key) { + throw(env, "setkey()/getkey() temporarily not suppoted"); +} + +JNIEXPORT +jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_nhandlerCapacity( + JNIEnv *env, jobject this) { + throw(env, "setkey()/getkey() temporarily not suppoted"); +} + + +JNIEXPORT +jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_ngetBaseAddress(JNIEnv *env, + jobject this, jlong id) { + pthread_rwlock_rdlock(&g_vmem_rwlock); + void *md = *(g_vmp_ptr + id); + jlong ret = (long) b_addr(md); + pthread_rwlock_unlock(&g_vmem_rwlock); + return ret; +} + JNIEXPORT jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_VMemServiceImpl_ninit(JNIEnv *env, jclass this, jlong capacity, jstring pathname, jboolean isnew) {