chiark / gitweb /
new mapping arrangements - before tidy
authorian <ian>
Tue, 12 Feb 2008 23:17:53 +0000 (23:17 +0000)
committerian <ian>
Tue, 12 Feb 2008 23:17:53 +0000 (23:17 +0000)
hostside/persist.c
hostside/realtime.c
hostside/realtime.h

index 1f5f07a6b24d8b44d0d00bf6d057bb2ba91a103c..e95aca1a526e778254bccb51110f9033cacbd5a7 100644 (file)
@@ -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);
index 6cd3a2e60be3bf33f101e2cea92a4335a8164501..c20ce3819c8f76653bc9eab758ab9afb54d081ce 100644 (file)
@@ -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();
index 786e30be1ab788329b6b81d30d4c0d64d61fdf8e..aff15cb61e4190dabfe0861cf663d9f59aa39d18 100644 (file)
@@ -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);