Skip to content

Commit

Permalink
Basic mmap based cache for entry mapping only, supporting DRAM<->PMEM…
Browse files Browse the repository at this point in the history
… cross storage
  • Loading branch information
EngineersBox committed Feb 18, 2022
1 parent 1eb4268 commit 4524e56
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 80 deletions.
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ list (REMOVE_DUPLICATES includeDirs)
add_executable(PMEM_mmap_IO ${sourceFiles})
target_include_directories(PMEM_mmap_IO PRIVATE ${includeDirs})

set(PMDK_INCLUDE "C:/Users/DEG3NERAT3_/vcpkg/packages/pmdk_x64-windows/include")
set(PMDK_LIBRARIES "C:/Users/DEG3NERAT3_/vcpkg/packages/pmdk_x64-windows/lib")
target_include_directories(PMEM_mmap_IO PRIVATE ${PMDK_INCLUDE})
target_link_libraries(PMEM_mmap_IO PRIVATE ${PMDK_LIBRARIES})
#set(PMDK_INCLUDE "C:/Users/DEG3NERAT3_/vcpkg/packages/pmdk_x64-windows/include")
#set(PMDK_LIBRARIES "C:/Users/DEG3NERAT3_/vcpkg/packages/pmdk_x64-windows/lib")
#target_include_directories(PMEM_mmap_IO PRIVATE ${PMDK_INCLUDE})
#target_link_libraries(PMEM_mmap_IO PRIVATE ${PMDK_LIBRARIES})
100 changes: 24 additions & 76 deletions src/main.c
Original file line number Diff line number Diff line change
@@ -1,89 +1,37 @@
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <libpmem.h>
#include "structure/cache.h"

/* using 1k of pmem for this example */
#define PMEM_LEN 1024

// Maximum length of our buffer
#define MAX_BUF_LEN 30

/****************************
* This function writes the "Hello..." string to persistent-memory.
*****************************/
void write_hello_string (char *buf, char *path) {
char *pmemaddr;
size_t mapped_len;
int is_pmem;
int main(int argc, char *argv[]) {
cache c;
void* entryAlloc = allocateEntries(&c, 5);

/* create a pmem file and memory map it */
if ((pmemaddr = (char *) pmem_map_file(
path,
PMEM_LEN,
PMEM_FILE_CREATE,
0666,
&mapped_len,
&is_pmem
)) == NULL) {
perror("pmem_map_file");
exit(1);
if (entryAlloc == MAP_FAILED || entryAlloc == NULL) {
printf("Mapping Failed\n");
return 1;
}
/* store a string to the persistent memory */
strcpy(pmemaddr, buf);

/* flush above strcpy to persistence */
if (is_pmem)
pmem_persist(pmemaddr, mapped_len);
else
pmem_msync(pmemaddr, mapped_len);

/* output a string from the persistent memory to console */
printf("\nWrite the (%s) string to persistent memory.\n",pmemaddr);
}

/****************************
* This function reads the "Hello..." string from persistent-memory.
*****************************/
void read_hello_string(char *path) {
char *pmemaddr;
size_t mapped_len;
int is_pmem;

/* open the pmem file to read back the data */
if ((pmemaddr = (char *) pmem_map_file(
path,
PMEM_LEN,
PMEM_FILE_CREATE,
0666,
&mapped_len,
&is_pmem
)) == NULL) {
perror("pmem_map_file");
exit(1);
int8_t put_result = putEntry(&c, (cache_entry){ .ttl = 100, .value = 42 });
if (put_result == -1) {
printf("Unable to put entry into cache\n");
free(c.entries);
return 1;
}
/* Reading the string from persistent-memory and write to console */
printf("\nRead the (%s) string from persistent memory.\n",pmemaddr);
}

/****************************
* This main function gather from the command line and call the appropriate
* functions to perform read and write persistently to memory.
*****************************/
int main(int argc, char *argv[]) {
char *path = argv[2];
cache_entry* returned = getEntry(&c, 0);
if (returned == NULL) {
printf("Could not get entry at index 0 from cache\n");
free(c.entries);
return 1;
}

// Create the string to save to persistent memory
char buf[MAX_BUF_LEN] = "Hello Persistent Memory!!!";
printf("Value: %d, TTL: %d\n", returned->value, returned->ttl);

if (strcmp (argv[1], "-w") == 0) {
write_hello_string (buf, path);
} else if (strcmp (argv[1], "-r") == 0) {
read_hello_string(path);
} else {
fprintf(stderr, "Usage: %s <-w/-r> <filename>\n", argv[0]);
exit(1);
if (freeEntries(&c) != 0) {
printf("UnMapping Failed\n");
return 1;
}

return 0;
}
44 changes: 44 additions & 0 deletions src/structure/cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "cache.h"
#include <stdio.h>
#include <sys/mman.h>

cache_entry* getEntry(cache* ptr, uint32_t index) {
if (ptr == NULL || ptr->count <= index) {
return NULL;
}
return &ptr->entries[index];
}

int8_t putEntry(cache* ptr, cache_entry entry) {
if (ptr == NULL
|| ptr->count >= ptr->allocatedSize
|| ptr->entries == NULL
|| ptr->entries == MAP_FAILED) {
return -1;
}
ptr->entries[ptr->count++] = entry;
return 0;
}

void* allocateEntries(cache* ptr, size_t size) {
if (ptr == NULL || size > MAX_CACHE_ENTRIES) {
return NULL;
}
ptr->allocatedSize = size;
ptr->count = 0;
return ptr->entries = mmap(
NULL,
size * sizeof(cache_entry),
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
0,
0
);
}

int8_t freeEntries(cache* ptr) {
if (ptr == NULL) {
return -1;
}
return munmap(ptr->entries, ptr->allocatedSize * sizeof(cache_entry));
}
24 changes: 24 additions & 0 deletions src/structure/cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#ifndef PMEM_MMAP_IO_CACHE_H
#define PMEM_MMAP_IO_CACHE_H

#include <stdint.h>
#include <stdlib.h>
#include "entry.h"

#define MAX_CACHE_ENTRIES 10

typedef struct {
size_t allocatedSize;
size_t count;
cache_entry* entries;
} cache;

cache_entry* getEntry(cache* ptr, uint32_t index);
int8_t putEntry(cache* ptr, cache_entry entry);

void* allocateEntries(cache* ptr, size_t count);
int8_t freeEntries(cache* ptr);

#endif //PMEM_MMAP_IO_CACHE_H
13 changes: 13 additions & 0 deletions src/structure/entry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#ifndef PMEM_MMAP_IO_ENTRY_H
#define PMEM_MMAP_IO_ENTRY_H

#include <stdint.h>

typedef struct {
uint16_t ttl;
int value;
} cache_entry;

#endif //PMEM_MMAP_IO_ENTRY_H

0 comments on commit 4524e56

Please sign in to comment.