This is an automated email from the ASF dual-hosted git repository. xjiao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mnemonic.git
commit 24a8ca3ecbc0d31add638e70a0c4e9b94c7bcaa6 Author: Yanhui Zhao <[email protected]> AuthorDate: Thu Aug 19 21:52:40 2021 -0700 MNEMONIC-673: Add pmalloc package into mnemonic source to reduce external dependencies --- .../src/main/native/CMakeLists.txt | 27 +- .../src/main/native/pmaddress.c | 33 ++ .../src/main/native/pmalign.c | 51 +++ .../src/main/native/pmalloc.c | 48 +++ .../src/main/native/pmalloc.h | 87 ++++ .../src/main/native/pmattach.c | 75 ++++ .../src/main/native/pmcalloc.c | 28 ++ .../src/main/native/pmcheck.c | 138 +++++++ .../src/main/native/pmdetach.c | 40 ++ .../src/main/native/pmfree.c | 53 +++ .../src/main/native/pmfunction.c | 455 +++++++++++++++++++++ .../src/main/native/pmfunction.h | 74 ++++ .../src/main/native/pminternal.h | 129 ++++++ .../src/main/native/pmkeys.c | 39 ++ .../src/main/native/pmmap.c | 82 ++++ .../src/main/native/pmrealloc.c | 93 +++++ .../src/main/native/pmreport.c | 33 ++ .../src/main/native/pmsync.c | 27 ++ .../src/main/native/pmvalloc.c | 29 ++ 19 files changed, 1536 insertions(+), 5 deletions(-) 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 @@ include_directories(${JNI_INCLUDE_DIRS}) 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)); +} +
