MNEMONIC-673: Add pmalloc package into mnemonic source to reduce external dependencies
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/CMakeLists.txt b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/CMakeLists.txt
index 8a988a0..4d2af75 100644
--- a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/CMakeLists.txt
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/CMakeLists.txt
@@ -40,12 +40,29 @@
find_package(Threads REQUIRED)
include_directories(${CMAKE_THREAD_LIBS_INIT})
-find_library(LIBPMALLOC_LIBRARIES NAMES libpmalloc_static.a)
-if (NOT LIBPMALLOC_LIBRARIES)
- message(FATAL_ERROR "not found pmalloc library")
-endif (NOT LIBPMALLOC_LIBRARIES)
+#find_library(LIBPMALLOC_LIBRARIES NAMES libpmalloc_static.a)
+#if (NOT LIBPMALLOC_LIBRARIES)
+# message(FATAL_ERROR "not found pmalloc library")
+#endif (NOT LIBPMALLOC_LIBRARIES)
-add_library(pmallocallocator SHARED common.c org_apache_mnemonic_service_memory_internal_PMallocServiceImpl.c)
+add_library(pmallocallocator SHARED
+ common.c
+ org_apache_mnemonic_service_memory_internal_PMallocServiceImpl.c
+ pmaddress.c
+ pmalign.c
+ pmattach.c
+ pmcalloc.c
+ pmcheck.c
+ pmdetach.c
+ pmfree.c
+ pmfunction.c
+ pmkeys.c
+ pmmap.c
+ pmrealloc.c
+ pmreport.c
+ pmsync.c
+ pmvalloc.c
+)
target_include_directories(pmallocallocator PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(pmallocallocator ${LIBPMALLOC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmaddress.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmaddress.c
new file mode 100644
index 0000000..ffb1ec9
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmaddress.c
@@ -0,0 +1,33 @@
+/*
+ * 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 "pminternal.h"
+
+inline void * p_addr(void *md, void *addr) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ return NULL == addr ? NULL : addr - (size_t) (mdp->mempoolbase);
+}
+
+inline void * e_addr(void *md, void *addr) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ return NULL == addr ? NULL : (size_t) addr + mdp->mempoolbase;
+}
+
+inline void * b_addr(void *md) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ return mdp->mempoolbase;
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalign.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalign.c
new file mode 100644
index 0000000..8a7f00a
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalign.c
@@ -0,0 +1,51 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+void *pmalign(void *md, size_t alignment, size_t size) {
+ void * result;
+ unsigned long int adj;
+ struct alignlist *ablist;
+ struct mdesc *mdp = (struct mdesc *) md;
+
+ if ((result = pmalloc(md, size + alignment - 1)) != NULL) {
+ adj = RESIDUAL(result, alignment);
+ if (adj != 0) {
+ for (ablist = mdp->aligned_blocks; ablist != NULL;
+ ablist = ablist->next) {
+ if (ablist->alignedaddr == NULL) {
+ break;
+ }
+ }
+ if (ablist == NULL) {
+ ablist = (struct alignlist *) pmalloc(md,
+ sizeof(struct alignlist));
+ if (ablist == NULL) {
+ pmfree(md, result);
+ return (NULL);
+ }
+ ablist->next = mdp->aligned_blocks;
+ mdp->aligned_blocks = ablist;
+ }
+ ablist->unalignedaddr = result;
+ result = ablist->alignedaddr = (char *) result + alignment - adj;
+ }
+ }
+ return (result);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalloc.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalloc.c
new file mode 100644
index 0000000..70e585e
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalloc.c
@@ -0,0 +1,48 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+void * pmalloc(void *md, size_t size) {
+ assert(NULL != md);
+ struct mdesc *mdp = (struct mdesc *) md;
+ void *result = NULL;
+
+ if (size == 0) {
+ return (NULL);
+ }
+
+ if (!(mdp->flags & PMALLOC_INITIALIZED)) {
+ if (!initialize(mdp)) {
+ return (NULL);
+ }
+ }
+
+ if (size < sizeof(struct list)) {
+ size = sizeof(struct list);
+ }
+
+ if ( 0 ) { // (BLOCKSIZE / 2) {
+ result = allocate_blockfrag(mdp, size);
+ } else {
+ size_t blocks = BLOCKIFY(size);
+ result = allocate_blocks(mdp, blocks);
+ }
+
+ return (result);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalloc.h b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalloc.h
new file mode 100644
index 0000000..cda39b7
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmalloc.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef PMALLOC_H
+#define PMALLOC_H 1
+
+#include <config.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stddef.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+
+#define PMALLOC_MIN_POOL_SIZE ((size_t)(1024 * 1024 * 16)) /* min pool size: 16MB */
+
+#define PMALLOC_KEYS 255
+
+extern void *pmopen(const char *fn, void *baseaddr, size_t initial_size);
+
+extern void pmclose(void* md);
+
+extern long pmcapacity(void* md);
+
+extern void * pmalloc(void *, size_t);
+
+extern void * pmalloc_check(void *, size_t, void *);
+
+extern void * pmrealloc(void *, void *, size_t);
+
+extern void * pmrealloc_check(void *, void *, size_t, void *);
+
+extern void * pmcalloc(void *, size_t, size_t);
+
+extern void * pmcalloc_check(void *, size_t, size_t, void *);
+
+extern void pmfree(void *, void *);
+
+extern void pmfree_check(void *, void *, void *);
+
+extern void * pmalign(void *, size_t, size_t);
+
+extern void * pmvalloc(void *, size_t);
+
+extern void pmcheck(void *, void (*)(void *, void *, int));
+
+extern struct mempoolstats pmstats(void *);
+
+extern void * pmalloc_attach(int, void *, size_t);
+
+extern void * pmalloc_detach(void *);
+
+extern int pmalloc_setkey(void *, int, void *);
+
+extern void * pmalloc_getkey(void *, int);
+
+extern int pmalloc_errno(void *);
+
+extern int pmtrace(void);
+
+extern int pmsync(void *, void *, size_t);
+
+extern void * p_addr(void *, void *);
+
+extern void * e_addr(void *, void *);
+
+extern void * b_addr(void *);
+
+#endif /* PMALLOC_H */
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmattach.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmattach.c
new file mode 100644
index 0000000..31790df
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmattach.c
@@ -0,0 +1,75 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+void * pmalloc_attach(int fd, void *baseaddr, size_t initial_size) {
+ struct mdesc mtemp;
+ struct mdesc *mdp;
+ void * mbase;
+ struct stat sbuf;
+
+ if (fd >= 0) {
+ if (fstat(fd, &sbuf) < 0) {
+ return (NULL);
+ } else if (sbuf.st_size > 0) {
+ return ((void *) reuse_mempool(fd));
+ }
+ }
+
+ mdp = &mtemp;
+ memset((char *) mdp, 0, sizeof(mtemp));
+ strncpy(mdp->magicwords, PMALLOC_MAGIC, PMALLOC_MAGIC_SIZE);
+ mdp->headersize = sizeof(mtemp);
+ mdp->version = PMALLOC_VERSION;
+ mdp->morespace = __pmalloc_map_morespace;
+ mdp->mappingfd = fd;
+ mdp->mempoolbase = mdp->watermarkpos = mdp->limitpos = baseaddr;
+
+ if (mdp->mappingfd < 0) {
+#ifdef HAVE_MMAP_ANON
+ mdp->flags |= MMALLOC_ANON;
+#else
+#ifdef HAVE_MMAP_DEV_ZERO
+ if ((mdp -> mappingfd = open ("/dev/zero", O_RDWR)) < 0)
+ {
+ return (NULL);
+ }
+ else
+ {
+ mdp -> flags |= PMALLOC_DEVZERO;
+ }
+#else
+ return NULL;
+#endif
+#endif
+ }
+
+ if ((mbase = mdp->morespace(mdp, sizeof(mtemp) + initial_size)) != NULL) {
+ memcpy(mbase, mdp, sizeof(mtemp));
+ mdp = (struct mdesc *) mbase;
+ mdp->morespace(mdp, -initial_size);
+ } else {
+ if (mdp->flags & PMALLOC_DEVZERO) {
+ close(mdp->mappingfd);
+ }
+ mdp = NULL;
+ }
+
+ return ((void *) mdp);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmcalloc.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmcalloc.c
new file mode 100644
index 0000000..d9dc934
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmcalloc.c
@@ -0,0 +1,28 @@
+/*
+ * 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 "pminternal.h"
+
+void * pmcalloc(void * md, size_t nmemb, size_t size) {
+ register void * result;
+
+ if ((result = pmalloc(md, nmemb * size)) != NULL) {
+ memset(result, 0, nmemb * size);
+ }
+ return (result);
+}
+
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmcheck.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmcheck.c
new file mode 100644
index 0000000..6a47a3f
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmcheck.c
@@ -0,0 +1,138 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+extern void abort(void);
+
+#define MAGICWORD (unsigned int) 0xd4c2afe9
+#define MAGICWORDFREE (unsigned int) 0xff04feca
+#define MAGICBYTE ((char) 0xd7)
+
+struct hdr {
+ union {
+ void *desc;
+ char pad[8];
+ } u;
+ unsigned int size;
+ unsigned int magic;
+};
+
+static void checkhdr(struct mdesc *mdp, const struct hdr *hdr) {
+ if (hdr->magic == MAGICWORDFREE) {
+ (*mdp->abortfunc)((void*) (&hdr[1]), hdr->u.desc, -1);
+ } else if (hdr->magic != MAGICWORD) {
+ (*mdp->abortfunc)((void*) (&hdr[1]), hdr->u.desc, 0);
+ } else if (((char*) &hdr[1])[hdr->size] != MAGICBYTE) {
+ (*mdp->abortfunc)((void *) (&hdr[1]), hdr->u.desc, 1);
+ }
+}
+
+void pmfree_check(void * md, void *ptr, void *desc) {
+ struct hdr *hdr = ((struct hdr *) ptr) - 1;
+ struct mdesc *mdp = (struct mdesc *) md;
+
+ checkhdr(mdp, hdr);
+ hdr->magic = MAGICWORDFREE;
+ pmfree(md, (void *) hdr);
+}
+
+void *pmalloc_check(void *md, size_t size, void *desc) {
+ struct hdr *hdr;
+ /* struct mdesc *mdp = (struct mdesc *) md; */
+ size_t nbytes;
+
+ nbytes = sizeof(struct hdr) + size + 1;
+ hdr = (struct hdr *) pmalloc(md, nbytes);
+ if (hdr != NULL) {
+ hdr->size = size;
+ hdr->u.desc = desc;
+ hdr->magic = MAGICWORD;
+ hdr++;
+ *((char *) hdr + size) = MAGICBYTE;
+ }
+ return ((void *) hdr);
+}
+
+void *pmcalloc_check(void *md, size_t num, size_t size, void *desc) {
+ register void * result;
+ if ((result = pmalloc_check(md, num * size, desc)) != NULL) {
+ bzero(result, num * size);
+ }
+ return (result);
+}
+
+void *pmrealloc_check(void *md, void *ptr, size_t size, void *desc) {
+ struct hdr *hdr;
+ struct mdesc *mdp = (struct mdesc *) md;
+ size_t nbytes;
+
+ if (ptr == NULL)
+ return pmalloc_check(md, size, desc);
+ hdr = ((struct hdr *) ptr) - 1;
+ checkhdr(mdp, hdr);
+ nbytes = sizeof(struct hdr) + size + 1;
+ hdr = (struct hdr *) pmrealloc(md, (void *) hdr, nbytes);
+ if (hdr != NULL) {
+ hdr->size = size;
+ hdr->u.desc = desc;
+ hdr++;
+ *((char *) hdr + size) = MAGICBYTE;
+ }
+ return ((void *) hdr);
+}
+
+static void default_abort(void *p, void *desc, int overflow) {
+ abort();
+}
+
+void pmcheck(void *md, void (*func)(void *, void *, int)) {
+ struct mdesc *mdp = (struct mdesc *) md;
+
+ mdp->abortfunc = (func != NULL ? func : default_abort);
+ mdp->flags |= PMALLOC_PMCHECK_USED;
+}
+
+int check_heap_free_info(struct mdesc *md) {
+ int ret = 0;
+ size_t start, current, next;
+ struct mdesc *mdp = md;
+ fprintf(stderr, "\n");
+
+ start = current = MALLOC_SEARCH_START;
+ do {
+ next = mdp->mblkinfo[current].free.next;
+
+ if (mdp->mblkinfo[next].free.prev != current) {
+ fprintf(stderr, "CURRENT->NEXT->prev IS NOT CURRENT !!! \n");
+ ret = -1;
+ break;
+ }
+
+ if (next == start)
+ break;
+
+ current = next;
+
+ fprintf(stderr, ".");
+ } while (1);
+
+ fprintf(stderr, "\n");
+ return ret;
+}
+
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmdetach.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmdetach.c
new file mode 100644
index 0000000..d7c68ed
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmdetach.c
@@ -0,0 +1,40 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+void *pmalloc_detach(void *md) {
+ struct mdesc mtemp;
+
+ if (md != NULL) {
+
+ mtemp = *(struct mdesc *) md;
+
+ if ((mtemp.morespace(&mtemp, mtemp.mempoolbase - mtemp.limitpos))
+ == NULL) {
+ *(struct mdesc *) md = mtemp;
+ } else {
+ if (mtemp.flags & PMALLOC_DEVZERO) {
+ close(mtemp.mappingfd);
+ }
+ md = NULL;
+ }
+ }
+
+ return (md);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfree.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfree.c
new file mode 100644
index 0000000..91bfd2b
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfree.c
@@ -0,0 +1,53 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+void __pmalloc_free(struct mdesc *mdp, void *addr) {
+ size_t block = BLOCK(addr);
+
+ int fragtype = mdp->mblkinfo[block].inuse.fragtype;
+ switch (fragtype) {
+ case 0:
+ free_blocks(mdp, block);
+ break;
+
+ default:
+ free_blockfrag(mdp, block, fragtype, addr);
+ break;
+ }
+}
+
+void pmfree(void *md, void *addr) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ register struct alignlist *l;
+
+ if (addr != NULL) {
+ for (l = mdp->aligned_blocks; l != NULL; l = l->next) {
+ if (l->alignedaddr == addr) {
+ l->alignedaddr = NULL;
+ addr = l->unalignedaddr;
+ break;
+ }
+ }
+ __pmalloc_free(mdp, addr);
+ // if (check_heap_free_info(mdp) < 0) exit(1);
+ }
+
+}
+
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfunction.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfunction.c
new file mode 100644
index 0000000..5b7c625
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfunction.c
@@ -0,0 +1,455 @@
+/*
+ * 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 "pmfunction.h"
+
+void rebase_mdesc_infos(struct mdesc * mdp, void *e_addr, void *o_addr) {
+ if (e_addr == o_addr)
+ return;
+ printf("Rebase Address from %p to %p \n", o_addr, e_addr);
+ //sleep(5);
+ ptrdiff_t off;
+ off = e_addr - o_addr;
+ assert(mdp != NULL);
+ mdp->mempoolbase = e_addr;
+ mdp->mblkinfo = REBASE_ADDRESS(mdp->mblkinfo, off);
+ mdp->watermarkpos = REBASE_ADDRESS(mdp->watermarkpos, off);
+ mdp->limitpos = REBASE_ADDRESS(mdp->limitpos, off);
+ mdp->mblkinfobase = REBASE_ADDRESS(mdp->mblkinfobase, off);
+ size_t idx;
+
+ /* not necessary to rebase all persistent key pointer since user do it instead more elegantly.
+ for (idx = 0; idx < PMALLOC_KEYS; ++idx) {
+ if (NULL != mdp -> keys[idx]) {
+ mdp -> keys[idx] = REBASE_ADDRESS(mdp -> keys[idx], off);
+ }
+ }
+ */
+
+ struct alignlist **pal = &mdp->aligned_blocks;
+ while (NULL != *pal) {
+ *pal = REBASE_ADDRESS(*pal, off);
+ pal = &(*pal)->next;
+ }
+
+ for (idx = 0; idx < BLOCKLOG; ++idx) {
+ struct list *plist = &mdp->fragblockhead[idx];
+ while (NULL != plist) {
+ if (NULL != plist->next) {
+ plist->next = REBASE_ADDRESS(plist->next, off);
+ }
+ if (NULL != plist->prev) {
+ plist->prev = REBASE_ADDRESS(plist->prev, off);
+ }
+ plist = plist->next;
+ }
+ }
+}
+
+struct mdesc * reuse_mempool(int fd) {
+ struct mdesc mtemp;
+ struct mdesc *mdp = NULL;
+
+ if ((lseek(fd, 0L, SEEK_SET) == 0)
+ && (read(fd, (char *) &mtemp, sizeof(mtemp)) == sizeof(mtemp))
+ && (mtemp.headersize == sizeof(mtemp))
+ && (strcmp(mtemp.magicwords, PMALLOC_MAGIC) == 0)
+ && (mtemp.version <= PMALLOC_VERSION)) {
+ mtemp.mappingfd = fd;
+
+ void * remap_base = __pmalloc_remap_mempool(&mtemp);
+ if (remap_base != MAP_FAILED) {
+ mdp = (struct mdesc *) remap_base;
+ rebase_mdesc_infos(mdp, remap_base, mdp->mempoolbase);
+ mdp->mappingfd = fd;
+ mdp->morespace = __pmalloc_map_morespace;
+ }
+ }
+ return (mdp);
+}
+
+void *align(struct mdesc * mdp, size_t size) {
+ void * result;
+ unsigned long int adj;
+
+ result = mdp->morespace(mdp, size);
+ adj = RESIDUAL(result, BLOCKSIZE);
+ if (adj != 0) {
+ adj = BLOCKSIZE - adj;
+ mdp->morespace(mdp, adj);
+ result = (char *) result + adj;
+ }
+ return (result);
+}
+
+int initialize(struct mdesc *mdp) {
+ mdp->mblkinfosize = INITMPOOLSIZE / BLOCKSIZE;
+ mdp->mblkinfo = (malloc_info *) align(mdp,
+ mdp->mblkinfosize * sizeof(malloc_info));
+ if (mdp->mblkinfo == NULL) {
+ return (0);
+ }
+ memset((void *) mdp->mblkinfo, 0, mdp->mblkinfosize * sizeof(malloc_info));
+ mdp->mblkinfo[0].free.size = 0;
+ mdp->mblkinfo[0].free.next = mdp->mblkinfo[0].free.prev = 0;
+ mdp->mblkinfosearchindex = 0;
+ mdp->mblkinfobase = (char *) mdp->mblkinfo;
+ mdp->flags |= PMALLOC_INITIALIZED;
+ return (1);
+}
+
+void *morespace(struct mdesc *mdp, size_t size) {
+ void * result;
+ malloc_info *newinfo, *oldinfo;
+ size_t newsize;
+
+ result = align(mdp, size);
+ if (result == NULL) {
+ return (NULL);
+ }
+
+ if ((size_t) BLOCK((char * ) result + size) > mdp->mblkinfosize) {
+ newsize = mdp->mblkinfosize;
+ while ((size_t) BLOCK((char * ) result + size) > newsize) {
+ newsize *= 2;
+ }
+ newinfo = (malloc_info *) align(mdp, newsize * sizeof(malloc_info));
+ if (newinfo == NULL) {
+ mdp->morespace(mdp, -size);
+ return (NULL);
+ }
+ memset((void *) newinfo, 0, newsize * sizeof(malloc_info));
+ memcpy((void *) newinfo, (void *) mdp->mblkinfo,
+ mdp->mblkinfosize * sizeof(malloc_info));
+ oldinfo = mdp->mblkinfo;
+ newinfo[BLOCK(oldinfo)].inuse.fragtype = 0;
+ newinfo[BLOCK(oldinfo)].inuse.info.sizeinblock = BLOCKIFY(
+ mdp->mblkinfosize * sizeof(malloc_info));
+ mdp->mblkinfo = newinfo;
+ __pmalloc_free(mdp, (void *) oldinfo);
+ mdp->mblkinfosize = newsize;
+ }
+
+ mdp->mblkinfoidxlimit = BLOCK((char * ) result + size);
+ return (result);
+}
+
+void *allocate_blockfrag(struct mdesc *mdp, size_t size)
+{
+ void * result = NULL;
+ size_t block;
+ register size_t i;
+ struct list *next;
+ register size_t log;
+
+ log = 1;
+ --size;
+ while ((size /= 2) != 0)
+ {
+ ++log;
+ }
+
+ next = mdp -> fragblockhead[log].next;
+ if (next != NULL)
+ {
+ result = (void *) next;
+ next -> prev -> next = next -> next;
+ if (next -> next != NULL)
+ {
+ next -> next -> prev = next -> prev;
+ }
+ block = BLOCK (result);
+ if (--mdp -> mblkinfo[block].inuse.info.frag.nfreefrags != 0)
+ {
+ mdp -> mblkinfo[block].inuse.info.frag.firstfragidxinlist =
+ RESIDUAL (next -> next, BLOCKSIZE) >> log;
+ }
+
+ mdp -> mblkstats.chunks_used++;
+ mdp -> mblkstats.bytes_used += 1 << log;
+ mdp -> mblkstats.chunks_free--;
+ mdp -> mblkstats.bytes_free -= 1 << log;
+ }
+ else
+ {
+ result = allocate_blocks (mdp, 1);
+ if (result != NULL)
+ {
+ for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i)
+ {
+ next = (struct list *) ((char *) result + (i << log));
+ next -> next = mdp -> fragblockhead[log].next;
+ next -> prev = &mdp -> fragblockhead[log];
+ next -> prev -> next = next;
+ if (next -> next != NULL)
+ {
+ next -> next -> prev = next;
+ }
+ }
+
+ block = BLOCK (result);
+ mdp -> mblkinfo[block].inuse.fragtype = log;
+ mdp -> mblkinfo[block].inuse.info.frag.nfreefrags = i - 1;
+ mdp -> mblkinfo[block].inuse.info.frag.firstfragidxinlist = i - 1;
+
+ mdp -> mblkstats.chunks_free += (BLOCKSIZE >> log) - 1;
+ mdp -> mblkstats.bytes_free += BLOCKSIZE - (1 << log);
+ mdp -> mblkstats.bytes_used -= BLOCKSIZE - (1 << log);
+ }
+ }
+
+ return result;
+}
+
+void *allocate_blocks(struct mdesc *mdp, size_t blocks)
+{
+ void * result = NULL;
+ size_t block, lastblocks, start;
+ start = block = MALLOC_SEARCH_START;
+ while (mdp -> mblkinfo[block].free.size < blocks)
+ {
+ block = mdp -> mblkinfo[block].free.next;
+ if (block == start)
+ {
+ block = mdp -> mblkinfo[0].free.prev;
+ lastblocks = mdp -> mblkinfo[block].free.size;
+ if (mdp -> mblkinfoidxlimit != 0 &&
+ block + lastblocks == mdp -> mblkinfoidxlimit &&
+ mdp -> morespace (mdp, 0) == ADDRESS(block + lastblocks) &&
+ (morespace (mdp, (blocks - lastblocks) * BLOCKSIZE)) != NULL)
+ {
+
+ block = mdp -> mblkinfo[0].free.prev;
+
+ mdp -> mblkinfo[block].free.size += (blocks - lastblocks);
+ mdp -> mblkstats.bytes_free +=
+ (blocks - lastblocks) * BLOCKSIZE;
+ continue;
+ }
+ result = morespace(mdp, blocks * BLOCKSIZE);
+ if (result != NULL)
+ {
+ block = BLOCK (result);
+ mdp -> mblkinfo[block].inuse.fragtype = 0;
+ mdp -> mblkinfo[block].inuse.info.sizeinblock = blocks;
+ mdp -> mblkstats.chunks_used++;
+ mdp -> mblkstats.bytes_used += blocks * BLOCKSIZE;
+ }
+ return (result);
+ }
+ }
+
+ result = ADDRESS(block);
+ if (mdp -> mblkinfo[block].free.size > blocks)
+ {
+ mdp -> mblkinfo[block + blocks].free.size
+ = mdp -> mblkinfo[block].free.size - blocks;
+ mdp -> mblkinfo[block + blocks].free.next
+ = mdp -> mblkinfo[block].free.next;
+ mdp -> mblkinfo[block + blocks].free.prev
+ = mdp -> mblkinfo[block].free.prev;
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.prev].free.next
+ = mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.prev
+ = mdp -> mblkinfosearchindex = block + blocks;
+ }
+ else
+ {
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.prev
+ = mdp -> mblkinfo[block].free.prev;
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.prev].free.next
+ = mdp -> mblkinfosearchindex = mdp -> mblkinfo[block].free.next;
+ mdp -> mblkstats.chunks_free--;
+ }
+
+ mdp -> mblkinfo[block].inuse.fragtype = 0;
+ mdp -> mblkinfo[block].inuse.info.sizeinblock = blocks;
+ mdp -> mblkstats.chunks_used++;
+ mdp -> mblkstats.bytes_used += blocks * BLOCKSIZE;
+ mdp -> mblkstats.bytes_free -= blocks * BLOCKSIZE;
+ return result;
+}
+
+void free_blocks(struct mdesc *mdp, size_t block)
+{
+ size_t blocks;
+ register size_t i;
+ /* struct list *prev, *next; */
+ mdp -> mblkstats.chunks_used--;
+ mdp -> mblkstats.bytes_used -=
+ mdp -> mblkinfo[block].inuse.info.sizeinblock * BLOCKSIZE;
+ mdp -> mblkstats.bytes_free +=
+ mdp -> mblkinfo[block].inuse.info.sizeinblock * BLOCKSIZE;
+
+ i = mdp -> mblkinfosearchindex;
+ if (i > block)
+ {
+ while (i > block)
+ {
+ i = mdp -> mblkinfo[i].free.prev;
+ }
+ }
+ else
+ {
+ do
+ {
+ i = mdp -> mblkinfo[i].free.next;
+ }
+ while ((i != 0) && (i < block));
+ i = mdp -> mblkinfo[i].free.prev;
+ }
+
+ if (block == i + mdp -> mblkinfo[i].free.size)
+ {
+ mdp -> mblkinfo[i].free.size +=
+ mdp -> mblkinfo[block].inuse.info.sizeinblock;
+ block = i;
+ }
+ else
+ {
+ mdp -> mblkinfo[block].free.size =
+ mdp -> mblkinfo[block].inuse.info.sizeinblock;
+ mdp -> mblkinfo[block].free.next = mdp -> mblkinfo[i].free.next;
+ mdp -> mblkinfo[block].free.prev = i;
+ mdp -> mblkinfo[i].free.next = block;
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.prev = block;
+ mdp -> mblkstats.chunks_free++;
+ }
+
+ if (block + mdp -> mblkinfo[block].free.size ==
+ mdp -> mblkinfo[block].free.next)
+ {
+ mdp -> mblkinfo[block].free.size
+ += mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.size;
+ mdp -> mblkinfo[block].free.next
+ = mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.next;
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.prev = block;
+ mdp -> mblkstats.chunks_free--;
+ }
+
+ blocks = mdp -> mblkinfo[block].free.size;
+ if (blocks >= FINAL_FREE_BLOCKS && block + blocks == mdp -> mblkinfoidxlimit
+ && mdp -> morespace (mdp, 0) == ADDRESS (block + blocks))
+ {
+ register size_t bytes = blocks * BLOCKSIZE;
+ mdp -> mblkinfoidxlimit -= blocks;
+ mdp -> morespace (mdp, -bytes);
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.prev].free.next
+ = mdp -> mblkinfo[block].free.next;
+ mdp -> mblkinfo[mdp -> mblkinfo[block].free.next].free.prev
+ = mdp -> mblkinfo[block].free.prev;
+ block = mdp -> mblkinfo[block].free.prev;
+ mdp -> mblkstats.chunks_free--;
+ mdp -> mblkstats.bytes_free -= bytes;
+ }
+
+ mdp -> mblkinfosearchindex = block;
+}
+
+void free_blockfrag(struct mdesc *mdp, size_t block, int fraglog, void *addr)
+{
+ /* size_t blocks; */
+ register size_t i;
+ struct list *prev, *next;
+
+ mdp -> mblkstats.chunks_used--;
+ mdp -> mblkstats.bytes_used -= 1 << fraglog;
+ mdp -> mblkstats.chunks_free++;
+ mdp -> mblkstats.bytes_free += 1 << fraglog;
+
+ prev = (struct list *)
+ ((char *) ADDRESS(block) +
+ (mdp -> mblkinfo[block].inuse.info.frag.firstfragidxinlist << fraglog));
+
+ if (mdp -> mblkinfo[block].inuse.info.frag.nfreefrags ==
+ (BLOCKSIZE >> fraglog) - 1)
+ {
+ next = prev;
+ for (i = 1; i < (size_t) (BLOCKSIZE >> fraglog); ++i)
+ {
+ next = next -> next;
+ }
+ prev -> prev -> next = next;
+ if (next != NULL)
+ {
+ next -> prev = prev -> prev;
+ }
+ mdp -> mblkinfo[block].inuse.fragtype = 0;
+ mdp -> mblkinfo[block].inuse.info.sizeinblock = 1;
+
+ mdp -> mblkstats.chunks_used++;
+ mdp -> mblkstats.bytes_used += BLOCKSIZE;
+ mdp -> mblkstats.chunks_free -= BLOCKSIZE >> fraglog;
+ mdp -> mblkstats.bytes_free -= BLOCKSIZE;
+
+ pmfree ((void *) mdp, (void *) ADDRESS(block));
+ }
+ else if (mdp -> mblkinfo[block].inuse.info.frag.nfreefrags != 0)
+ {
+ next = (struct list *) addr;
+ next -> next = prev -> next;
+ next -> prev = prev;
+ prev -> next = next;
+ if (next -> next != NULL)
+ {
+ next -> next -> prev = next;
+ }
+ ++mdp -> mblkinfo[block].inuse.info.frag.nfreefrags;
+ }
+ else
+ {
+ prev = (struct list *) addr;
+ mdp -> mblkinfo[block].inuse.info.frag.nfreefrags = 1;
+ mdp -> mblkinfo[block].inuse.info.frag.firstfragidxinlist =
+ RESIDUAL (addr, BLOCKSIZE) >> fraglog;
+ prev -> next = mdp -> fragblockhead[fraglog].next;
+ prev -> prev = &mdp -> fragblockhead[fraglog];
+ prev -> prev -> next = prev;
+ if (prev -> next != NULL)
+ {
+ prev -> next -> prev = prev;
+ }
+ }
+}
+
+void *pmopen(const char *fn, void *baseaddr, size_t initial_size)
+{
+ void *ret = NULL;
+ assert(NULL != fn);
+ int fd = open(fn, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
+ if(fd >= 0) {
+ ret = pmalloc_attach(fd, baseaddr, initial_size);
+ }
+ return ret;
+}
+
+long pmcapacity(void* md)
+{
+ struct mdesc *mdp = (struct mdesc *) md;
+ if (NULL == mdp->limitpos || NULL == mdp->mempoolbase ||
+ mdp->limitpos <= mdp->mempoolbase) {
+ return 0L;
+ }
+ return mdp->limitpos - mdp->mempoolbase;
+}
+
+void pmclose(void* md)
+{
+ struct mdesc *mdp = (struct mdesc *)md;
+ assert(NULL != mdp);
+ /* pmalloc_detach(md); */
+ close(mdp->mappingfd);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfunction.h b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfunction.h
new file mode 100644
index 0000000..e17d8cc
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmfunction.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef PMFUNCTION_H
+#define PMFUNCTION_H 1
+
+#include "config.h"
+#include "pminternal.h"
+
+#define PMALLOC_DEVZERO (1 << 0)
+
+#define PMALLOC_INITIALIZED (1 << 1)
+
+#define PMALLOC_PMCHECK_USED (1 << 2)
+
+#define PMALLOC_ANON (1 << 3)
+
+#define PMALLOC_FILE (1 << 4)
+
+#define REBASE_ADDRESS(A, O) ((void*)(A) + (O))
+
+#ifndef MIN
+# define MIN(A, B) ((A) < (B) ? (A) : (B))
+#endif
+
+#define BLOCKSIZE ((unsigned int) 1 << BLOCKLOG)
+#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
+
+#define RESIDUAL(addr, bsize) ((size_t) ((size_t)addr % (bsize)))
+
+#define BLOCK(A) (((char *) (A) - mdp -> mblkinfobase) / BLOCKSIZE + 1)
+
+#define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + mdp -> mblkinfobase))
+
+#ifndef HAVE_MEMMOVE
+# undef memmove
+# define memmove(dst,src,len) bcopy(src,dst,len)
+#endif
+
+#define INITMPOOLSIZE (INT_BIT > 16 ? 4 * 1024 * 1024 : 64 * 1024)
+
+void rebase_mdesc_infos(struct mdesc * mdp, void *e_addr, void *o_addr);
+
+struct mdesc *reuse_mempool(int);
+
+int initialize(struct mdesc *);
+
+void *morespace(struct mdesc *, size_t);
+
+void *align(struct mdesc *, size_t);
+
+void *allocate_blockfrag(struct mdesc *mdp, size_t size);
+
+void *allocate_blocks(struct mdesc *mdp, size_t blocks);
+
+void free_blocks(struct mdesc *mdp, size_t block);
+
+void free_blockfrag(struct mdesc *mdp, size_t block, int fraglog, void *addr);
+
+#endif /* PMFUNCTION_H */
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pminternal.h b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pminternal.h
new file mode 100644
index 0000000..8f9df10
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pminternal.h
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+#ifndef __PMINTERNAL_H
+#define __PMINTERNAL_H 1
+
+#include "pmalloc.h"
+
+#define PMALLOC_MAGIC "pmalloc_bigdata1"
+#define PMALLOC_MAGIC_SIZE 32
+#define PMALLOC_VERSION 2
+
+#define INT_BIT (CHAR_BIT * sizeof(int))
+
+#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
+
+#define FINAL_FREE_BLOCKS 8
+
+#define MALLOC_SEARCH_START mdp -> mblkinfosearchindex
+
+typedef union {
+ struct {
+ int fragtype;
+ union {
+ struct {
+ size_t nfreefrags;
+ size_t firstfragidxinlist;
+ } frag;
+ size_t sizeinblock;
+ } info;
+ } inuse;
+ struct {
+ size_t size;
+ size_t next;
+ size_t prev;
+ } free;
+} malloc_info;
+
+struct alignlist {
+ struct alignlist *next;
+ void *alignedaddr;
+ void *unalignedaddr;
+};
+
+struct list {
+ struct list *next;
+ struct list *prev;
+};
+
+struct mempoolstats {
+ size_t bytes_total;
+ size_t chunks_used;
+ size_t bytes_used;
+ size_t chunks_free;
+ size_t bytes_free;
+};
+
+struct mdesc {
+ char magicwords[PMALLOC_MAGIC_SIZE];
+
+ unsigned int headersize;
+
+ unsigned char version;
+
+ unsigned int flags;
+
+ int saved_errno;
+
+ void * (*morespace)(struct mdesc *, ptrdiff_t);
+
+ void (*abortfunc)(void *, void *, int);
+
+ size_t mblkinfosize;
+
+ char *mblkinfobase;
+
+ size_t mblkinfosearchindex;
+
+ size_t mblkinfoidxlimit;
+
+ malloc_info *mblkinfo;
+
+ struct mempoolstats mblkstats;
+
+ struct list fragblockhead[BLOCKLOG];
+
+ struct alignlist *aligned_blocks;
+
+ char *mempoolbase;
+
+ char *watermarkpos;
+
+ char *limitpos;
+
+ int mappingfd;
+
+ void *persistkeys[PMALLOC_KEYS];
+
+};
+
+extern void __pmalloc_free(struct mdesc *, void *);
+
+extern struct mdesc *__pmalloc_default_mdp;
+
+extern void * __pmalloc_map_morespace(struct mdesc *, ptrdiff_t);
+
+extern void * __pmalloc_remap_mempool(struct mdesc *);
+
+extern void * pmalloc_attach(int, void *, size_t);
+
+extern void * pmalloc_detach(void *);
+
+extern void rebase_mdesc_infos(struct mdesc *, void *, void *);
+
+#endif /* __PMINTERNAL_H */
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmkeys.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmkeys.c
new file mode 100644
index 0000000..b86c99d
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmkeys.c
@@ -0,0 +1,39 @@
+/*
+ * 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 "pminternal.h"
+
+int pmalloc_setkey(void *md, int keyidx, void *key) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ int result = 0;
+
+ if ((mdp != NULL) && (keyidx >= 0) && (keyidx < PMALLOC_KEYS)) {
+ mdp->persistkeys[keyidx] = key;
+ result++;
+ }
+ return (result);
+}
+
+void * pmalloc_getkey(void *md, int keyidx) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ void * keyval = NULL;
+
+ if ((mdp != NULL) && (keyidx >= 0) && (keyidx < PMALLOC_KEYS)) {
+ keyval = mdp->persistkeys[keyidx];
+ }
+ return (keyval);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmmap.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmmap.c
new file mode 100644
index 0000000..0b7bb1e
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmmap.c
@@ -0,0 +1,82 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+static size_t pagesize = 0;
+
+#define PAGE_ALIGN(addr) \
+ (void *) (((long)(addr) + pagesize - 1) & ~(pagesize - 1))
+
+void * __pmalloc_map_morespace(struct mdesc *mdp, ptrdiff_t size) {
+ void * result = NULL;
+ /* off_t foffset; */
+ size_t mapbytes;
+ void *moveto;
+ void *mapto;
+ char buf = 0;
+
+ if (pagesize == 0) {
+ pagesize = getpagesize();
+ }
+ if (size == 0) {
+ result = mdp->watermarkpos;
+ } else if (size < 0) {
+ if (mdp->watermarkpos + size >= mdp->mempoolbase) {
+ result = (void *) mdp->watermarkpos;
+ mdp->watermarkpos += size;
+ }
+ } else {
+ if (mdp->watermarkpos + size > mdp->limitpos) {
+ if (0 == mdp->limitpos) { /*Initial memory pool*/
+ assert(mdp->watermarkpos == 0);
+ moveto = PAGE_ALIGN(size);
+ mapbytes = (size_t) moveto;
+
+ if (!(mdp->flags & (PMALLOC_DEVZERO | PMALLOC_ANON))) {
+ lseek(mdp->mappingfd, mapbytes - 1, SEEK_SET);
+ if (write(mdp->mappingfd, &buf, 1) != 1)
+ return NULL;
+ }
+ mapto = mmap(NULL, mapbytes, PROT_READ | PROT_WRITE,
+ MAP_SHARED, mdp->mappingfd, 0);
+ if (mapto != MAP_FAILED) /* initial */
+ {
+ mdp->mempoolbase = mdp->watermarkpos = result = mapto;
+ mdp->watermarkpos += size;
+ mdp->limitpos = PAGE_ALIGN(mdp->watermarkpos);
+ }
+ }
+ } else {
+ result = (void *) mdp->watermarkpos;
+ mdp->watermarkpos += size;
+ }
+ }
+ return (result);
+}
+
+void * __pmalloc_remap_mempool(struct mdesc *mdp) {
+ void* base;
+
+ base = mmap(mdp->mempoolbase, (size_t) (mdp->limitpos - mdp->mempoolbase),
+ PROT_READ | PROT_WRITE, MAP_SHARED, mdp->mappingfd, 0);
+ if (base == MAP_FAILED) {
+ fprintf(stderr, "Mapping ERROR:(%d) %s \n", errno, strerror(errno));
+ }
+ return base;
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmrealloc.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmrealloc.c
new file mode 100644
index 0000000..bcd8c4a
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmrealloc.c
@@ -0,0 +1,93 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+void *pmrealloc(void *md, void *ptr, size_t size) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ void * result;
+ int type;
+ size_t block, blocks, oldlimit;
+
+ if (size == 0) {
+ if (ptr == NULL)
+ return NULL;
+ pmfree(md, ptr);
+ return (pmalloc(md, 0));
+ } else if (ptr == NULL) {
+ return (pmalloc(md, size));
+ }
+
+ block = BLOCK(ptr);
+
+ type = mdp->mblkinfo[block].inuse.fragtype;
+ switch (type) {
+ case 0:
+ if (size <= BLOCKSIZE / 2) {
+ result = pmalloc(md, size);
+ if (result != NULL) {
+ memcpy(result, ptr, size);
+ pmfree(md, ptr);
+ return (result);
+ }
+ }
+
+ blocks = BLOCKIFY(size);
+ if (blocks < mdp->mblkinfo[block].inuse.info.sizeinblock) {
+ mdp->mblkinfo[block + blocks].inuse.fragtype = 0;
+ mdp->mblkinfo[block + blocks].inuse.info.sizeinblock =
+ mdp->mblkinfo[block].inuse.info.sizeinblock - blocks;
+ mdp->mblkinfo[block].inuse.info.sizeinblock = blocks;
+ pmfree(md, ADDRESS(block + blocks));
+ result = ptr;
+ } else if (blocks == mdp->mblkinfo[block].inuse.info.sizeinblock) {
+ result = ptr;
+ } else {
+ blocks = mdp->mblkinfo[block].inuse.info.sizeinblock;
+ oldlimit = mdp->mblkinfoidxlimit;
+ mdp->mblkinfoidxlimit = 0;
+ pmfree(md, ptr);
+ mdp->mblkinfoidxlimit = oldlimit;
+ result = pmalloc(md, size);
+ if (result == NULL) {
+ pmalloc(md, blocks * BLOCKSIZE);
+ return (NULL);
+ }
+ if (ptr != result) {
+ memmove(result, ptr, blocks * BLOCKSIZE);
+ }
+ }
+ break;
+
+ default:
+ if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) {
+ result = ptr;
+ } else {
+ result = pmalloc(md, size);
+ if (result == NULL) {
+ return (NULL);
+ }
+ memcpy(result, ptr, MIN(size, (size_t ) 1 << type));
+ pmfree(md, ptr);
+ }
+ break;
+ }
+
+ return (result);
+}
+
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmreport.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmreport.c
new file mode 100644
index 0000000..7e2b88d
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmreport.c
@@ -0,0 +1,33 @@
+/*
+ * 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 "pmfunction.h"
+#include "pminternal.h"
+
+
+size_t report_used_inbyte(struct mdesc * mdp)
+{
+ assert(NULL != mdp);
+ return mdp -> mblkstats.bytes_used;
+}
+
+size_t report_free_inbyte(struct mdesc * mdp)
+{
+ assert(NULL != mdp);
+ return mdp -> mblkstats.bytes_free;
+}
+
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmsync.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmsync.c
new file mode 100644
index 0000000..aac44d9
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmsync.c
@@ -0,0 +1,27 @@
+/*
+ * 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 "pminternal.h"
+
+int pmsync(void *md, void *addr, size_t length) {
+ struct mdesc *mdp = (struct mdesc *) md;
+ int result = -1;
+ if (mdp->mempoolbase < (char*)addr && length > 0) {
+ result = msync(addr, length, MS_SYNC);
+ }
+ return (result);
+}
diff --git a/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmvalloc.c b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmvalloc.c
new file mode 100644
index 0000000..7b54d45
--- /dev/null
+++ b/mnemonic-memory-services/mnemonic-pmalloc-service/src/main/native/pmvalloc.c
@@ -0,0 +1,29 @@
+/*
+ * 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 "pminternal.h"
+
+static size_t pagesize;
+
+void * pmvalloc(void *md, size_t size) {
+ if (pagesize == 0) {
+ pagesize = getpagesize();
+ }
+
+ return (pmalign(md, pagesize, size));
+}
+