Mem: Allow serializing of more than INT_MAX bytes
authorMarco Elver <marco.elver@ed.ac.uk>
Mon, 10 Sep 2012 15:57:43 +0000 (11:57 -0400)
committerMarco Elver <marco.elver@ed.ac.uk>
Mon, 10 Sep 2012 15:57:43 +0000 (11:57 -0400)
Despite gzwrite taking an unsigned for length, it returns an int for
bytes written; gzwrite fails if (int)len < 0.  Because of this, call
gzwrite with len no larger than INT_MAX: write in blocks of INT_MAX if
data to be written is larger than INT_MAX.

src/mem/abstract_mem.cc

index a7016bb514229314b575c183ffa8a3db0038b435..775517e3b26a50156b7e6bf22360a54c21374a3a 100644 (file)
@@ -51,6 +51,7 @@
 
 #include <cerrno>
 #include <cstdio>
+#include <climits>
 #include <iostream>
 #include <string>
 
@@ -486,9 +487,17 @@ AbstractMemory::serialize(ostream &os)
         fatal("Insufficient memory to allocate compression state for %s\n",
                 filename);
 
-    if (gzwrite(compressedMem, pmemAddr, size()) != (int)size()) {
-        fatal("Write failed on physical memory checkpoint file '%s'\n",
-              filename);
+    uint64_t pass_size = 0;
+    // gzwrite fails if (int)len < 0 (gzwrite returns int)
+    for (uint64_t written = 0; written < size(); written += pass_size) {
+        pass_size = (uint64_t)INT_MAX < (size() - written) ?
+            (uint64_t)INT_MAX : (size() - written);
+
+        if (gzwrite(compressedMem, pmemAddr + written,
+                    (unsigned int) pass_size) != (int)pass_size) {
+            fatal("Write failed on physical memory checkpoint file '%s'\n",
+                  filename);
+        }
     }
 
     if (gzclose(compressedMem))