[Mesa-dev] [RFC 15/20] glsl: add capability to read/map files to memory_map

Tapani Pälli tapani.palli at intel.com
Mon Jun 2 05:05:56 PDT 2014


Patch provides mmap version and a simple/slow version if mmap is not
available. This functionality will be used by the binary shader cache.

Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
 src/glsl/memory_map.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/glsl/memory_map.h b/src/glsl/memory_map.h
index bc02d89..2de42de 100644
--- a/src/glsl/memory_map.h
+++ b/src/glsl/memory_map.h
@@ -26,6 +26,14 @@
 #ifndef MEMORY_MAP_H
 #define MEMORY_MAP_H
 
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef _POSIX_MAPPED_FILES
+#include <sys/mman.h>
+#include <sys/stat.h>
+#endif
+
 #include <stdint.h>
 #include <string.h>
 #include "ralloc.h"
@@ -35,21 +43,67 @@
 /**
  * Helper class to read data
  *
- * Class reads data from user given memory.
+ * Class can read either from user given memory or from a file. On Linux
+ * file reading wraps around the Posix functions for mapping a file into
+ * the process's address space. Other OS may need different implementation.
  */
 class memory_map
 {
 public:
    memory_map() :
       error(false),
+      mode(memory_map::READ_MEM),
       cache_size(0),
       cache_mmap(NULL),
       cache_mmap_p(NULL)
    {
-      /* only used by read_string() */
       mem_ctx = ralloc_context(NULL);
    }
 
+   /* read from disk */
+   int map(const char *path)
+   {
+#ifdef _POSIX_MAPPED_FILES
+      struct stat stat_info;
+      if (stat(path, &stat_info) != 0)
+         return -1;
+
+      mode = memory_map::READ_MAP;
+      cache_size = stat_info.st_size;
+
+      int fd = open(path, O_RDONLY);
+      if (fd) {
+         cache_mmap_p = cache_mmap = (char *)
+            mmap(NULL, cache_size, PROT_READ, MAP_PRIVATE, fd, 0);
+         close(fd);
+         return (cache_mmap == MAP_FAILED) ? -1 : 0;
+      }
+#else
+      /* Implementation for systems without mmap(). */
+      FILE *in = fopen(path, "r");
+      if (in) {
+         fseek(in, 0, SEEK_END);
+         cache_size = ftell(in);
+         rewind(in);
+
+         cache_mmap = ralloc_array(mem_ctx, char, cache_size);
+
+         if (!cache_mmap)
+            return -1;
+
+         if (fread(cache_mmap, cache_size, 1, in) != 1) {
+            ralloc_free(cache_mmap);
+            cache_mmap = NULL;
+         }
+         cache_mmap_p = cache_mmap;
+         fclose(in);
+
+         return (cache_mmap == NULL) ? -1 : 0;
+      }
+#endif
+      return -1;
+   }
+
    /* read from memory */
    void map(const void *memory, size_t size)
    {
@@ -58,6 +112,11 @@ public:
    }
 
    ~memory_map() {
+#ifdef _POSIX_MAPPED_FILES
+      if (cache_mmap && mode == READ_MAP) {
+         munmap(cache_mmap, cache_size);
+      }
+#endif
       ralloc_free(mem_ctx);
    }
 
@@ -155,6 +214,13 @@ private:
    /* if errors have occured during reading */
    bool error;
 
+   /* specifies if we are reading mapped memory or user passed mem */
+   enum read_mode {
+      READ_MEM = 0,
+      READ_MAP
+   };
+
+   int32_t mode;
    unsigned cache_size;
    char *cache_mmap;
    char *cache_mmap_p;
-- 
1.8.3.1



More information about the mesa-dev mailing list