-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bf8bf14
commit 0cd7a8b
Showing
1 changed file
with
74 additions
and
74 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,74 @@ | ||
// Persistent stack example of how mmap() naturally creates a software abstraction of persistent memory. | ||
// Author: Terence Kelly | ||
// tpkelly @ { acm.org, cs.princeton.edu, eecs.umich.edu } | ||
|
||
// Note: Use 'truncate' to make the initial (empty) backing file, | ||
// whose size should be a multiple of the system page size: | ||
// | ||
// prompt> getconf PAGESIZE | ||
// 4096 | ||
// prompt> truncate -s 4096 ps.img | ||
// | ||
// makes a 4096-byte empty file. The first sizeof(size_t) bytes will | ||
// be interprted as the number of items on the stack; the remainder | ||
// of the file will contain the integers contained in the stack. | ||
// Now you can run the program: | ||
// | ||
// prompt> ./pstack 7 13 47 pop | ||
// 47 | ||
// prompt> ./pstack pop pop 99 | ||
// 13 | ||
// 7 | ||
// prompt> ./pstack pop | ||
// 99 | ||
// | ||
// Notice that items push'd in one invocation of the program persist | ||
// until the next invocation: The stack is persistent. | ||
// | ||
// You can use hexdump to examine the contents of the backing file: | ||
// | ||
// prompt> hexdump ps.img | ||
|
||
#include <assert.h> | ||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <sys/mman.h> | ||
#include <sys/stat.h> | ||
#include <sys/types.h> | ||
|
||
typedef struct { | ||
size_t n; | ||
int stack[]; // zero-length per C99 | ||
} pstack_t; | ||
|
||
int main(int argc, char *argv[]) { | ||
int fd, rc; | ||
struct stat s; | ||
size_t file_size; | ||
pstack_t *p; | ||
|
||
fd = open("ps.img", O_RDWR); | ||
assert(fd > -1); | ||
rc = fstat(fd, &s); | ||
assert(rc == 0); | ||
|
||
file_size = (size_t) s.st_size; | ||
assert(file_size >= sizeof(pstack_t) && file_size % sizeof(int) == 0); | ||
|
||
p = (pstack_t *) mmap(NULL, file_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
assert(p != MAP_FAILED); | ||
|
||
for (int i = 1; i < argc; i++) | ||
if (strcmp(argv[i], "pop") == 0) { | ||
if (p->n > 0) // stack not empty | ||
printf("%d\n", p->stack[--p->n]); | ||
} else { // push | ||
if (sizeof(pstack_t) + (1 + p->n) * sizeof(int) <= file_size) // stack not full | ||
p->stack[p->n++] = atoi(argv[i]); | ||
} | ||
(void) close(fd); | ||
return 0; | ||
} | ||
// Persistent stack example of how mmap() naturally creates a software abstraction of persistent memory. | ||
// Author: Terence Kelly | ||
// tpkelly @ { acm.org, cs.princeton.edu, eecs.umich.edu } | ||
|
||
// Note: Use 'truncate' to make the initial (empty) backing file, | ||
// whose size should be a multiple of the system page size: | ||
// | ||
// prompt> getconf PAGESIZE | ||
// 4096 | ||
// prompt> truncate -s 4096 ps.img | ||
// | ||
// makes a 4096-byte empty file. The first sizeof(size_t) bytes will | ||
// be interprted as the number of items on the stack; the remainder | ||
// of the file will contain the integers contained in the stack. | ||
// Now you can run the program: | ||
// | ||
// prompt> ./pstack 7 13 47 pop | ||
// 47 | ||
// prompt> ./pstack pop pop 99 | ||
// 13 | ||
// 7 | ||
// prompt> ./pstack pop | ||
// 99 | ||
// | ||
// Notice that items push'd in one invocation of the program persist | ||
// until the next invocation: The stack is persistent. | ||
// | ||
// You can use hexdump to examine the contents of the backing file: | ||
// | ||
// prompt> hexdump ps.img | ||
|
||
#include <assert.h> | ||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <sys/mman.h> | ||
#include <sys/stat.h> | ||
#include <sys/types.h> | ||
|
||
typedef struct { | ||
size_t n; | ||
int stack[]; // zero-length per C99 | ||
} pstack_t; | ||
|
||
int main(int argc, char *argv[]) { | ||
int fd, rc; | ||
struct stat s; | ||
size_t file_size; | ||
pstack_t *p; | ||
|
||
fd = open("ps.img", O_RDWR); | ||
assert(fd > -1); | ||
rc = fstat(fd, &s); | ||
assert(rc == 0); | ||
|
||
file_size = (size_t) s.st_size; | ||
assert(file_size >= sizeof(pstack_t) && file_size % sizeof(int) == 0); | ||
|
||
p = (pstack_t *) mmap(NULL, file_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
assert(p != MAP_FAILED); | ||
|
||
for (int i = 1; i < argc; i++) | ||
if (strcmp(argv[i], "pop") == 0) { | ||
if (p->n > 0) // stack not empty | ||
printf("%d\n", p->stack[--p->n]); | ||
} else { // push | ||
if (sizeof(pstack_t) + (1 + p->n) * sizeof(int) <= file_size) // stack not full | ||
p->stack[p->n++] = atoi(argv[i]); | ||
} | ||
(void) close(fd); | ||
return 0; | ||
} |