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));
+}
+