Be a bit more efficient when processing the active and inactive
[oota-llvm.git] / tools / llee / StorageProxy.c
1 /*===- StorageProxy.c - OS implementation of the caching interface --------===*\
2  *                                                                            *
3  * This file implements the interface that we will expect operating           *
4  * systems to implement if they wish to support offline cachine.              *
5  *                                                                            *
6 \*===----------------------------------------------------------------------===*/
7
8 #include "OSInterface.h"
9 #include "SysUtils.h"
10 #include "Config/fcntl.h"
11 #include "Config/unistd.h"
12 #include "Config/sys/types.h"
13 #include "Config/sys/stat.h"
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17
18 static const char CacheRoot[] = "/tmp/LLVMCache";
19 static const char ExeSuffix[] = ".exe";
20
21 char* computeCachedFile(const char *key) {
22   /* CacheRoot + "/" + std::string(key) + ExeSuffix; */
23   char *cacheFile = (char*) malloc(strlen(CacheRoot) + 1 + strlen(key) + 
24                                    strlen(ExeSuffix) + 1);
25   char *pCacheFile = cacheFile;
26   if (!cacheFile) return 0;
27   memcpy(cacheFile, CacheRoot, strlen(CacheRoot));
28   pCacheFile += strlen(CacheRoot);
29   *pCacheFile++ = '/';
30   memcpy(pCacheFile, key, strlen(key));
31   pCacheFile += strlen(key);
32   memcpy(pCacheFile, ExeSuffix, strlen(ExeSuffix));
33   pCacheFile += strlen(ExeSuffix);
34   *pCacheFile = 0; // Null-terminate
35   return cacheFile;
36 }
37
38 /*
39  * llvmStat - equivalent to stat(3), except the key may not necessarily
40  * correspond to a file by that name, implementation is up to the OS.
41  * Values returned in buf are similar as they are in Unix.
42  */
43 void llvmStat(const char *key, struct stat *buf) {
44   char* cacheFile = computeCachedFile(key);
45   fprintf(stderr, "llvmStat(%s)\n", cacheFile);
46   stat(cacheFile, buf);
47   free(cacheFile);
48 }
49
50 /*
51  * llvmWriteFile - implements a 'save' of a file in the OS. 'key' may not
52  * necessarily map to a file of the same name.
53  * Returns:
54  * 0 - success
55  * non-zero - error
56  */ 
57 int llvmWriteFile(const char *key, const void *data, size_t len)
58 {
59   char* cacheFile = computeCachedFile(key);
60   int fd = open(cacheFile, O_CREAT|O_WRONLY|O_TRUNC);
61   free(cacheFile);
62   if (fd < 0) return -1; // encountered an error
63   if (write(fd, data, len)) return -1;
64   if (fsync(fd)) return -1;
65   if (close(fd)) return -1;
66   return 0;
67 }
68
69 /* 
70  * llvmReadFile - tells the OS to load data corresponding to a particular key
71  * somewhere into memory.
72  * Returns:
73  * 0 - failure
74  * non-zero - address of loaded file
75  *
76  * Value of size is the length of data loaded into memory.
77  */ 
78 void* llvmReadFile(const char *key, size_t *size) {
79   char* cacheFile = computeCachedFile(key);
80   if (!cacheFile) return 0;
81   struct stat buf;
82   stat(cacheFile, &buf);
83   int fd = open(cacheFile, O_RDONLY);
84   if (fd < 0) return 0; // encountered an error
85   void* data = malloc(buf.st_size);
86   if (read(fd, data, buf.st_size)) {
87     free(data);  
88     return 0;
89   }
90   *size = buf.st_size;
91   return data;
92 }
93
94 /*
95  * llvmExecve - execute a file from cache. This is a temporary proof-of-concept
96  * because we do not relocate what we can read from disk.
97  */
98 int llvmExecve(const char *filename, char *const argv[], char *const envp[]) {
99   char* cacheFile = computeCachedFile(filename);
100   executeProgram(cacheFile, argv, envp);
101 }