版权声明: 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;
}