blob: b3bf39120b586816011a3678c852d84e4cd79133 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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
*
* http://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.
*/
#include "org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl.h"
#include <pmalloc.h>
typedef struct {
//size_t size;
jlong size;
} PMBHeader;
#define PMBHSZ (sizeof(PMBHeader))
static void **g_pmp_ptr = NULL;
static size_t g_pmp_count = 0;
static pthread_mutex_t *g_pmalloc_mutex_ptr = NULL;
static pthread_rwlock_t g_pmp_rwlock = PTHREAD_RWLOCK_INITIALIZER;
/******************************************************************************
** JNI implementations
*****************************************************************************/
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nallocate(JNIEnv* env,
jobject this, jlong id, jlong size, jboolean initzero) {
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
jlong ret = 0L;
void *md = *(g_pmp_ptr + id);
void* nativebuf = initzero ? pmcalloc(md, 1, size + PMBHSZ) : pmalloc(md, size + PMBHSZ);
if (NULL != nativebuf) {
((PMBHeader *) nativebuf)->size = size + PMBHSZ;
ret = addr_to_java(nativebuf + PMBHSZ);
// fprintf(stderr, "### nallocate size: %lld, %X, header size: %ld ### \n",
// ((PMBHeader *)nativebuf)->size, nativebuf-b_addr(*(g_pmp_ptr + id)), PMBHSZ);
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nreallocate(JNIEnv* env,
jobject this, jlong id, jlong address, jlong size, jboolean initzero) {
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
jlong ret = 0L;
void *md = *(g_pmp_ptr + id);
void* nativebuf = NULL;
void* p = addr_from_java(address);
if (NULL != p) {
nativebuf = pmrealloc(md, p - PMBHSZ, size + PMBHSZ);
} else {
nativebuf = initzero ? pmcalloc(md, 1, size + PMBHSZ) : pmalloc(md, size + PMBHSZ);
}
if (nativebuf != NULL) {
((PMBHeader *) nativebuf)->size = size + PMBHSZ;
ret = addr_to_java(nativebuf + PMBHSZ);
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nfree(
JNIEnv* env,
jobject this, jlong id,
jlong address)
{
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
//fprintf(stderr, "nfree Get Called %ld, %X\n", id, address);
void *md = *(g_pmp_ptr + id);
void* nativebuf = addr_from_java(address);
if (nativebuf != NULL) {
// fprintf(stderr, "### nfree size: %lld, %X ###, header size: %ld \n",
// ((PMBHeader *)(nativebuf - PMBHSZ))->size, nativebuf - PMBHSZ-b_addr(*(g_pmp_ptr + id)), PMBHSZ);
pmfree(md, nativebuf - PMBHSZ);
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
}
JNIEXPORT
void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nsync(
JNIEnv* env,
jobject this, jlong id)
{
}
JNIEXPORT
jobject JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_ncreateByteBuffer(
JNIEnv *env, jobject this, jlong id, jlong size) {
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
jobject ret = NULL;
void *md = *(g_pmp_ptr + id);
void* nativebuf = pmalloc(md, size + PMBHSZ);
if (NULL != nativebuf) {
((PMBHeader *) nativebuf)->size = size + PMBHSZ;
ret = (*env)->NewDirectByteBuffer(env, nativebuf + PMBHSZ, size);
// fprintf(stderr, "### ncreateByteBuffer size: %lld, %X ###, header size: %ld \n",
// ((PMBHeader *)nativebuf)->size, nativebuf-b_addr(*(g_pmp_ptr + id)), PMBHSZ);
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
jobject JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nretrieveByteBuffer(
JNIEnv *env, jobject this, jlong id, jlong e_addr) {
jobject ret = NULL;
void* p = addr_from_java(e_addr);
if (NULL != p) {
void* nativebuf = p - PMBHSZ;
ret = (*env)->NewDirectByteBuffer(env, p, ((PMBHeader *) nativebuf)->size - PMBHSZ);
}
return ret;
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nretrieveSize(JNIEnv *env,
jobject this, jlong id, jlong e_addr) {
jlong ret = 0L;
void* p = addr_from_java(e_addr);
if (NULL != p) {
void* nativebuf = p - PMBHSZ;
ret = ((PMBHeader *) nativebuf)->size - PMBHSZ;
// fprintf(stderr, "### nretrieveSize size: %lld, %X ###, header size: %ld \n",
// ((PMBHeader *)nativebuf)->size, nativebuf-b_addr(*(g_pmp_ptr + id)), PMBHSZ);
}
return ret;
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_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_PMallocServiceImpl_nresizeByteBuffer(
JNIEnv *env, jobject this, jlong id, jobject bytebuf, jlong size) {
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
jobject ret = NULL;
void *md = *(g_pmp_ptr + id);
if (NULL != bytebuf) {
void* nativebuf = (*env)->GetDirectBufferAddress(env, bytebuf);
if (nativebuf != NULL) {
nativebuf = pmrealloc(md, nativebuf - PMBHSZ, size + PMBHSZ);
if (NULL != nativebuf) {
((PMBHeader *) nativebuf)->size = size + PMBHSZ;
ret = (*env)->NewDirectByteBuffer(env, nativebuf + PMBHSZ, size);
}
}
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_ndestroyByteBuffer(
JNIEnv *env, jobject this, jlong id, jobject bytebuf)
{
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
void *md = *(g_pmp_ptr + id);
if (NULL != bytebuf) {
void* nativebuf = (*env)->GetDirectBufferAddress(env, bytebuf);
if (nativebuf != NULL) {
// fprintf(stderr, "### ndestroyByteBuffer size: %lld, %X, header size: %ld ### \n",
// ((PMBHeader *)(nativebuf - PMBHSZ))->size, nativebuf - PMBHSZ -b_addr(*(g_pmp_ptr + id)), PMBHSZ);
pmfree(md, nativebuf - PMBHSZ);
}
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
}
JNIEXPORT
void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nsetHandler(
JNIEnv *env, jobject this, jlong id, jlong key, jlong value)
{
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
void *md = *(g_pmp_ptr + id);
if (id < PMALLOC_KEYS && id >= 0) {
pmalloc_setkey(md, key, (void*)value);
}
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_ngetHandler(JNIEnv *env,
jobject this, jlong id, jlong key) {
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
void *md = *(g_pmp_ptr + id);
jlong ret = (id < PMALLOC_KEYS && id >= 0) ? (long) pmalloc_getkey(md, key) : 0;
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nhandlerCapacity(
JNIEnv *env, jobject this) {
return PMALLOC_KEYS;
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_ngetBaseAddress(JNIEnv *env,
jobject this, jlong id) {
pthread_rwlock_rdlock(&g_pmp_rwlock);
void *md = *(g_pmp_ptr + id);
jlong ret = (long) b_addr(md);
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
jlong JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_ninit(JNIEnv *env,
jclass this, jlong capacity, jstring pathname, jboolean isnew) {
pthread_rwlock_wrlock(&g_pmp_rwlock);
size_t ret = -1;
void *md = NULL;
const char* mpathname = (*env)->GetStringUTFChars(env, pathname, NULL);
if (NULL == mpathname) {
pthread_rwlock_unlock(&g_pmp_rwlock);
throw(env, "Big memory path not specified!");
}
if ((md = pmopen(mpathname, NULL, capacity)) == NULL) {
pthread_rwlock_unlock(&g_pmp_rwlock);
throw(env, "Big memory init failure!");
}
(*env)->ReleaseStringUTFChars(env, pathname, mpathname);
g_pmp_ptr = realloc(g_pmp_ptr, (g_pmp_count + 1) * sizeof(void*));
g_pmalloc_mutex_ptr = realloc(g_pmalloc_mutex_ptr, (g_pmp_count + 1) * sizeof(pthread_mutex_t));
if (NULL != g_pmp_ptr && NULL != g_pmalloc_mutex_ptr) {
*(g_pmp_ptr + g_pmp_count) = md;
pthread_mutex_init(g_pmalloc_mutex_ptr + g_pmp_count, NULL);
ret = g_pmp_count;
++g_pmp_count;
} else {
pthread_rwlock_unlock(&g_pmp_rwlock);
throw(env, "Big memory init Out of memory!");
}
pthread_rwlock_unlock(&g_pmp_rwlock);
return ret;
}
JNIEXPORT
void JNICALL Java_org_apache_mnemonic_service_allocatorservice_internal_PMallocServiceImpl_nclose
(JNIEnv *env, jobject this, jlong id)
{
pthread_rwlock_rdlock(&g_pmp_rwlock);
pthread_mutex_lock(g_pmalloc_mutex_ptr + id);
void *md = *(g_pmp_ptr + id);
pmclose(md);
*(g_pmp_ptr + id) = NULL;
pthread_mutex_unlock(g_pmalloc_mutex_ptr + id);
pthread_mutex_destroy(g_pmalloc_mutex_ptr + id);
pthread_rwlock_unlock(&g_pmp_rwlock);
}
__attribute__((destructor)) void fini(void) {
int i;
if (NULL != g_pmp_ptr) {
for (i = 0; i < g_pmp_count; ++i) {
if (NULL != *(g_pmp_ptr + i)) {
pmclose(*(g_pmp_ptr + i));
*(g_pmp_ptr + i) = NULL;
pthread_mutex_destroy(g_pmalloc_mutex_ptr + i);
}
}
free(g_pmp_ptr);
g_pmp_ptr = NULL;
free(g_pmalloc_mutex_ptr);
g_pmalloc_mutex_ptr = NULL;
g_pmp_count = 0;
}
pthread_rwlock_destroy(&g_pmp_rwlock);
}