pstack updated
This commit is contained in:
@@ -1,10 +1,33 @@
|
|||||||
// Persistent stack example of how mmap() naturally creates a software abstraction of persistent memory.
|
// Persistent stack example of how mmap() naturally creates a software abstraction of persistent memory.
|
||||||
// Author: Terence Kelly <tpklly@acm.org>
|
// Author: Terence Kelly
|
||||||
|
// tpkelly @ { acm.org, cs.princeton.edu, eecs.umich.edu }
|
||||||
|
|
||||||
// Note: Use 'dd' to make the initial (empty) image, e.g.,
|
// Note: Use 'truncate' to make the initial (empty) backing file,
|
||||||
// dd if=/dev/zero of=ps.img bs=32 count=1
|
// whose size should be a multiple of the system page size:
|
||||||
// makes a 32-byte empty file (the first integer being the size of the stack,
|
//
|
||||||
// the remaining integers being values)
|
// 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 <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -16,24 +39,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
int open_or_die(const char *path, int oflag) {
|
|
||||||
int fd = open(path, oflag);
|
|
||||||
assert(fd > 0);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fstat_or_die(int fildes, struct stat *buf) {
|
|
||||||
int rc = fstat(fildes, buf);
|
|
||||||
assert(rc == 0);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mmap_or_die(void *addr, size_t len, int prot, int flags, int fd, off_t offset) {
|
|
||||||
void *p = mmap(addr, len, prot, flags, fd, offset);
|
|
||||||
assert(p != MAP_FAILED);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t n;
|
size_t n;
|
||||||
int stack[]; // zero-length per C99
|
int stack[]; // zero-length per C99
|
||||||
@@ -45,26 +50,25 @@ int main(int argc, char *argv[]) {
|
|||||||
size_t file_size;
|
size_t file_size;
|
||||||
pstack_t *p;
|
pstack_t *p;
|
||||||
|
|
||||||
fd = open_or_die("ps.img", O_RDWR);
|
fd = open("ps.img", O_RDWR);
|
||||||
rc = fstat_or_die(fd, &s);
|
assert(fd > -1);
|
||||||
|
rc = fstat(fd, &s);
|
||||||
|
assert(rc == 0);
|
||||||
|
|
||||||
file_size = (size_t) s.st_size;
|
file_size = (size_t) s.st_size;
|
||||||
assert(file_size % sizeof(int) == 0);
|
assert(file_size >= sizeof(pstack_t) && file_size % sizeof(int) == 0);
|
||||||
|
|
||||||
p = mmap_or_die(NULL, file_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 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++)
|
for (int i = 1; i < argc; i++)
|
||||||
if (strcmp(argv[i], "pop") == 0) {
|
if (strcmp(argv[i], "pop") == 0) {
|
||||||
if (p->n > 0) // stack not empty
|
if (p->n > 0) // stack not empty
|
||||||
printf("%d\n", p->stack[--p->n]);
|
printf("%d\n", p->stack[--p->n]);
|
||||||
else
|
} else { // pop
|
||||||
printf("stack empty\n");
|
if (sizeof(pstack_t) + (1 + p->n) * sizeof(int) <= file_size) // stack not full
|
||||||
} else
|
p->stack[p->n++] = atoi(argv[i]);
|
||||||
if (sizeof(pstack_t) + p->n * sizeof(int) < file_size) // stack not full
|
}
|
||||||
p->stack[p->n++] = atoi(argv[i]);
|
(void) close(fd);
|
||||||
else
|
|
||||||
printf("stack full: %d not added\n", atoi(argv[i]));
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user