-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic mmap based cache for entry mapping only, supporting DRAM<->PMEM…
… cross storage
- Loading branch information
1 parent
1eb4268
commit 4524e56
Showing
5 changed files
with
109 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |