From: ian Date: Tue, 12 Feb 2008 23:17:53 +0000 (+0000) Subject: new mapping arrangements - before tidy X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=2c5ca26badd2b6020236af587c311caff507eedf;p=trains.git new mapping arrangements - before tidy --- diff --git a/hostside/persist.c b/hostside/persist.c index 1f5f07a..e95aca1 100644 --- a/hostside/persist.c +++ b/hostside/persist.c @@ -158,6 +158,80 @@ void persist_entrails_interpret(void) { (persist_record_converted= 0); } +/*---------- stupid mmap workaround ----------*/ + +static Byte resaddrbuf[1024*1024], *resaddrbegin; +static long pagesize; +static unsigned long resaddruse; + +#define RESADDR_DIEFMT "(persist mapping parameters:" \ + " %p+0x%lx%%0x%lx->%p+0x%lx)" +#define RESADDR_DIEARGS resaddrbuf,(unsigned long)sizeof(resaddrbuf), \ + pagesize, resaddrbegin,resaddruse + +static void resaddrdiee(const char *why) { + diee("%s " RESADDR_DIEFMT, why, RESADDR_DIEARGS); +} + +static void showmaps(int lno) { + FILE *f; + int c; + fprintf(stderr,"=======%d======\n",lno); + f= fopen("/proc/self/maps","r"); if (!f) diee("open maps"); + while ((c=getc(f)) != EOF) + fputc(c,stderr); + if (ferror(f)) diee("read maps"); + fclose(f); +system("grep Committed_AS /proc/meminfo"); +} + +#define SHOWMAPS showmaps(__LINE__); + +void persist_map_veryearly(void) { + int r; + +SHOWMAPS + + errno= 0; pagesize= sysconf(_SC_PAGE_SIZE); + if (pagesize<=0) diee("could not find pagesize"); + + if (pagesize & (pagesize-1)) return; + if (pagesize > sizeof(resaddrbuf)/2) return; + + resaddrbegin= (void*)(((unsigned long)resaddrbuf + pagesize - 1) & + ~(pagesize - 1UL)); + resaddruse= sizeof(resaddrbuf) - pagesize; + + r= mprotect(resaddrbegin,resaddruse,PROT_READ); + if (r) resaddrdiee("mprotect reserve buffer"); + +SHOWMAPS +} + +static void *mapmem(int fd, int datalen, int prot) { + void *rv; + int r; + + if (!resaddruse) + die("inappropriate combination of sizes " RESADDR_DIEFMT, RESADDR_DIEARGS); + + if (datalen > resaddruse) + die("data length %d too large " RESADDR_DIEFMT, datalen, RESADDR_DIEARGS); + + r= munmap(resaddrbegin, resaddruse); + if (r) resaddrdiee("munmap reserve buffer"); + + rv= mmap(resaddrbegin, datalen, prot, MAP_SHARED|MAP_FIXED, fd, 0); + if (rv == MAP_FAILED) + resaddrdiee(prot==(PROT_READ|PROT_WRITE) ? "map data rw" : + prot==PROT_READ ? "map data ro" : "map data badly"); + + assert(rv == resaddrbegin); + +SHOWMAPS + return rv; +} + /*---------- installing of our data as the current one ----------*/ void persist_install(void) { @@ -267,8 +341,7 @@ void *record_allocate(int datalen_spec) { fd= fileno(data); - mapbase= mmap(0, datalen, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (mapbase == MAP_FAILED) diee("could not write mmap persist data file"); + mapbase= mapmem(fd, datalen, PROT_READ|PROT_WRITE); return mapbase; } @@ -307,8 +380,7 @@ static void *persist_mapread(void) { #define PHI_LOAD(x) phi_load(&(x), sizeof(x), &offset); DO_PERSIST_HEADER_ITEMS(PHI_CHECK, PHI_LOAD, PHI_LOAD) - rv= mmap(0, datalen, PROT_READ|PROT_WRITE, MAP_PRIVATE, 0,0); - if (rv == MAP_FAILED) diee("could not read mmap persist data file"); + rv= mapmem(0, datalen, PROT_READ|PROT_WRITE); return rv; } @@ -320,6 +392,7 @@ void persist_entrails_run_converter(void) { realbase= persist_mapread(); adjust= (Byte*)realbase - (Byte*)mapbase; + assert(!adjust); #define CP(lvalue) \ ((lvalue)= (lvalue) ? (void*)((Byte*)(lvalue) + adjust) : 0); diff --git a/hostside/realtime.c b/hostside/realtime.c index 6cd3a2e..c20ce38 100644 --- a/hostside/realtime.c +++ b/hostside/realtime.c @@ -339,6 +339,8 @@ int main(int argc, const char **argv) { const char *arg; int r; + persist_map_veryearly(); + if (argv[0] && argv[1] && !strcmp(argv[1],PERSIST_CONVERT_OPTION)) /* do this before we call malloc so that MAP_FIXED is sure to work */ persist_entrails_run_converter(); diff --git a/hostside/realtime.h b/hostside/realtime.h index 786e30b..aff15cb 100644 --- a/hostside/realtime.h +++ b/hostside/realtime.h @@ -100,6 +100,8 @@ void persist_install(void); extern const char *persist_fn; extern const char *persist_record_converted; +void persist_map_veryearly(void); + /*---------- from/for realtime.c ----------*/ void oupicio(const char *dirn, const PicInsnInfo *pii, int objnum);