例程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//);
/* 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 : ;
}
char *pmem_str10 = (char *)memkind_malloc(pmem_kind, );
if (pmem_str10 == NULL) {
perror("memkind_malloc()");
fprintf(stderr, "Unable to allocate pmem string (pmem_str10)\n");
return errno ? -errno : ;
}
/* next chunk mapping */
char *pmem_str11 = (char *)memkind_malloc(pmem_kind, * * ); //8M
if (pmem_str11 == NULL) {
perror("memkind_malloc()");
fprintf(stderr, "Unable to allocate pmem string (pmem_str11)\n");
return errno ? -errno : ;
}
/* extend the heap #1 */
char *pmem_str12 = (char *)memkind_malloc(pmem_kind, * * ); //16M
if (pmem_str12 == NULL) {
perror("memkind_malloc()");
fprintf(stderr, "Unable to allocate pmem string (pmem_str12)\n");
return errno ? -errno : ;
}
/* OOM #1 */
char *pmem_str = (char *)memkind_malloc(pmem_kind, * * ); //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 : ;
}
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 ;
運作結果:
$ ./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: M
Hello world from persistent memory
将PMEM_MAX_SIZE的值,從原來的(MEMKIND_PMEM_MIN_SIZE * 2)修改為(MEMKIND_PMEM_MIN_SIZE * 1)後,運作的結果如下:
PMEM_MAX_SIZE: M
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 = ;
int oerrno;
char fullname[strlen(dir) + sizeof (template)];
(void) strcpy(fullname, dir);
(void) strcat(fullname, template);
if ((*fd = mkstemp(fullname)) < ) {
perror("mkstemp()");
err = MEMKIND_ERROR_RUNTIME;
goto exit;
}
(void) unlink(fullname);
if (ftruncate(*fd, size) != ) {
err = MEMKIND_ERROR_RUNTIME;
goto exit;
}
*addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, );
if (*addr == MAP_FAILED) {
err = MEMKIND_ERROR_RUNTIME;
goto exit;
}
return err;
exit:
oerrno = errno;
if (*fd != -) {
(void) close(*fd);
}
*fd = -;
*addr = NULL;
errno = oerrno;
return err;
}