我正在为我的 postscript 解释器构建一个内存管理器,我希望它能够将会话挂起到磁盘并恢复保存的会话。我使用匿名设计它mmap
,一切似乎都有效。测试代码访问内存似乎没有问题。但是现在我已经删除MAP_ANONYMOUS
并提供了一个O_RDWR
文件描述符,测试运行后我看不到文件中的内存内容。
#include <stdlib.h> /* exit free malloc realloc */
#include <stdio.h> /* fprintf printf perror */
#include <string.h> /* memset */
#include <unistd.h> /* getpagesize */
#include <sys/stat.h> /* open */
#include <fcntl.h> /* open */
/* placeholder error function */
/* ultimately, this will do a longjmp back to the central loop */
void error(char *msg) {
fprintf(stderr, "%s\n", msg);
perror("last system error:");
exit(EXIT_FAILURE);
}
unsigned pgsz /*= getpagesize()*/; /*=4096 (usually on 32bit)*/
/*
typedef struct {
unsigned char *base;
unsigned used;
unsigned max;
} mfile;
*/
/* dump mfile details to stdout */
void dumpmfile(mfile *mem){
printf("{mfile: base = %p, "
"used = 0x%x (%u), "
"max = 0x%x (%u)}\n",
mem->base,
mem->used, mem->used,
mem->max, mem->max);
unsigned u;
for (u=0; u < mem->used; u++) {
if (u%16 == 0) {
printf("\n%06u %04x: ", u, u);
}
printf("%02x ", (unsigned) mem->base[u]);
}
puts("");
}
/* memfile exists in path */
int getmemfile(){
int fd;
fd = open(
"x.mem",
O_RDWR);
return fd;
}
/* initialize the memory file */
void initmem(mfile *mem){
int fd;
struct stat buf;
size_t sz = pgsz;
fd = getmemfile();
if (fd != -1){
fstat(fd, &buf);
sz = buf.st_size;
if (sz < pgsz) sz = pgsz;
}
#ifdef MMAP
mem->base = mmap(NULL,
sz,
PROT_READ|PROT_WRITE,
MAP_PRIVATE
# ifndef MREMAP
|MAP_AUTOGROW
# endif
| (fd == -1? MAP_ANONYMOUS : 0) , fd, 0);
if (mem->base == MAP_FAILED)
#else
mem->base = malloc(pgsz);
if (mem->base == NULL)
#endif
error("unable to initialize memory file");
mem->used = 0;
mem->max = pgsz;
}
/* destroy the memory file */
void exitmem(mfile *mem){
#ifdef MMAP
munmap(mem->base, mem->max);
#else
free(mem->base);
#endif
mem->base = NULL;
mem->used = 0;
mem->max = 0;
}
// ... omitting some address table functions not relevant here.
mfile mem;
/* initialize everything */
void init(void){
pgsz = getpagesize();
initmem(&mem);
(void)initmtab(&mem); /* create mtab at address zero */
}
void xit(void){
exitmem(&mem);
}
int main(){
init();
unsigned ent;
int seven = 7;
int ret;
//printf("getmemfile: %d\n", getmemfile());
ent = mtalloc(&mem, 0, sizeof seven);
put(&mem, ent, 0, sizeof seven, &seven);
get(&mem, ent, 0, sizeof seven, &ret);
printf("put %d, got %d\n", seven, ret);
unsigned ent2;
ent2 = mtalloc(&mem, 0, 8*sizeof seven);
put(&mem, ent2, 6, sizeof seven, &seven);
get(&mem, ent2, 6, sizeof seven, &ret);
printf("put %d in slot 7, got %d\n", seven, ret);
//get(&mem, ent2, 9, sizeof seven, &ret);
//printf("attempted to retrieve element 10 from an 8-element array, got %d\n", ret);
unsigned ent3;
char str[] = "beads in buddha's necklace";
char sret[sizeof str];
ent3 = mtalloc(&mem, 0, strlen(str)+1);
put(&mem, ent3, 0, sizeof str, str);
get(&mem, ent3, 0, sizeof str, sret);
printf("stored and retrieved %s\n", sret);
xit();
return 0;
}
运行测试,检查文件。
乔什@Z1 ~/xpost $ 进行测试 cc -g -Wall -Wextra -DTESTMODULE -om mc ./ob && ./m 放 7,得到 7 将 7 放入插槽 7,得到 7 佛项链中的珠子储存和取回 乔什@Z1 ~/xpost $ od x.mem 0000000 000000 000000 000000 000000 000000 000000 000000 000000 * 0200000 乔什@Z1 ~/xpost $
我需要以某种方式冲洗它吗?或关闭文件?哦。废话,我敢打赌,不是吗?好吧,我花了一些精力打字,所以我会分享。如果它过于本地化,那就这样吧。没有。close
根本不会改变输出。
更新:现在看来一切正常。最后几个问题是硬编码文件名,在 open() 调用中省略 O_CREAT。和其他小错误。我已经添加msync
了很好的措施,但这MAP_SHARED
是对上述问题的修复。此模块和相关模块可在http://code.google.com/p/xpost/source/browse/查看。