Memkind 例程2 自定义memkind调用memkind_malloc()

版权声明: https://blog.csdn.net/qccz123456/article/details/81902970

例程2 自定义memkind调用memkind_malloc()
Key:
memkind_create_pmem()  // 创建pmem内存池
memkind_malloc()  // 从pmem内存中malloc出一块小内存
memkind_free()  // 释放这款小内存
memkind_create_pmem2()  //自定义函数:可以显式的创建pmem文件

#include <sys/param.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

#include <memkind.h>
#include <memkind/internal/memkind_pmem.h>

#define PMEM_MAX_SIZE   (MEMKIND_PMEM_MIN_SIZE * 2)

int main(int argc, char *argv[])
{
    struct memkind *pmem_kind;

    printf("PMEM_MAX_SIZE: %dM\n", PMEM_MAX_SIZE/1024/1024);

    /* create PMEM partition */
    //int err = memkind_create_pmem2(".", "pmem.001", PMEM_MAX_SIZE, &pmem_kind);
    int err = memkind_create_pmem(".", PMEM_MAX_SIZE, &pmem_kind);
    if (err) {
        perror("memkind_create_pmem()");
        fprintf(stderr, "Unable to create pmem partition\n");
        return errno ? -errno : 1;
    }

    char *pmem_str10 = (char *)memkind_malloc(pmem_kind, 512);
    if (pmem_str10 == NULL) {
        perror("memkind_malloc()");
        fprintf(stderr, "Unable to allocate pmem string (pmem_str10)\n");
        return errno ? -errno : 1;
    }

    /* next chunk mapping */
    char *pmem_str11 = (char *)memkind_malloc(pmem_kind, 8 * 1024 * 1024);  //8M
    if (pmem_str11 == NULL) {
        perror("memkind_malloc()");
        fprintf(stderr, "Unable to allocate pmem string (pmem_str11)\n");
        return errno ? -errno : 1;
    }

    /* extend the heap #1 */
    char *pmem_str12 = (char *)memkind_malloc(pmem_kind, 16 * 1024 * 1024);  //16M
    if (pmem_str12 == NULL) {
        perror("memkind_malloc()");
        fprintf(stderr, "Unable to allocate pmem string (pmem_str12)\n");
        return errno ? -errno : 1;
    }

    /* OOM #1 */
    char *pmem_str = (char *)memkind_malloc(pmem_kind, 16 * 1024 * 1024);  //16M
    if (pmem_str != NULL) {
        perror("memkind_malloc()");
        fprintf(stderr,
                "Failure, this allocation should not be possible (expected result was NULL)\n");
        return errno ? -errno : 1;
    }

    printf("Hello world from persistent memory\n");

    memkind_free(pmem_kind, pmem_str10);
    memkind_free(pmem_kind, pmem_str11);
    memkind_free(pmem_kind, pmem_str12);

    return 0;

运行结果:

$ ./compile.sh
rm -f ./pmem_example
para="-Wall -Werror -D_GNU_SOURCE -DMEMKIND_INTERNAL_API -DJE_PREFIX=jemk_ -g -O2 -pthread"
gcc $para -o pmem_example pmem_example.c -I/root/changqing/all_memkind/library/include -L/root/changqing/all_memkind/library/lib -lmemkind -I/root/changqing/all_memkind/memkind-back/jemalloc/obj/include -L/root/changqing/all_memkind/memkind-back/jemalloc/obj/lib -ljemalloc
$ ./run.sh
export LD_LIBRARY_PATH=/root/changqing/all_memkind/library/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/root/changqing/all_memkind/memkind-back/jemalloc/obj/lib:$LD_LIBRARY_PATH
./pmem_example
output:
PMEM_MAX_SIZE: 32M
Hello world from persistent memory

将PMEM_MAX_SIZE的值,从原来的(MEMKIND_PMEM_MIN_SIZE * 2)修改为(MEMKIND_PMEM_MIN_SIZE * 1)后,运行的结果如下:

PMEM_MAX_SIZE: 16M
memkind_malloc(): Success
Unable to allocate pmem string (pmem_str12)

原因是因为?

memkind_create_pmem()函数基本内容是新建文件、将文件进行map,得到指向文件的指针,最后封装到memkind对应的数据结构中,大致过程如下:

int pmem_tmpfile(const char *dir, size_t size, int *fd, void **addr)
{
    static char template[] = "/pmem.XXXXXX";
    int err = 0;
    int oerrno;

    char fullname[strlen(dir) + sizeof (template)];
    (void) strcpy(fullname, dir);
    (void) strcat(fullname, template);

    if ((*fd = mkstemp(fullname)) < 0) {
        perror("mkstemp()");
        err = MEMKIND_ERROR_RUNTIME;
        goto exit;
    }

    (void) unlink(fullname);

    if (ftruncate(*fd, size) != 0) {
        err = MEMKIND_ERROR_RUNTIME;
        goto exit;
    }

    *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
    if (*addr == MAP_FAILED) {
        err = MEMKIND_ERROR_RUNTIME;
        goto exit;
    }

    return err;

exit:
    oerrno = errno;
    if (*fd != -1) {
        (void) close(*fd);
    }
    *fd = -1;
    *addr = NULL;
    errno = oerrno;
    return err;
}

猜你喜欢

转载自blog.csdn.net/qccz123456/article/details/81902970
今日推荐