commit a464fd64f191299d6b5a0e38d691100665d66b1b
parent a5f81e8e1e0cc0e7a7c56b90d36263801e0944a6
Author: Kyle Milz <kyle@0x30.net>
Date:   Mon, 22 Aug 2016 19:33:34 -0600
src: let runtime write page aligned
Diffstat:
| M | src/runtime.c |  |  | 86 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- | 
1 file changed, 44 insertions(+), 42 deletions(-)
diff --git a/src/runtime.c b/src/runtime.c
@@ -14,10 +14,11 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <sys/mman.h>		/* shm_open, mmap */
-#include <sys/stat.h>		/* S_*USR */
+#include <sys/stat.h>		/* S_IRUSR, S_IWUSR, mkdir */
 
 #include <assert.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>		/* O_CREAT */
 #include <limits.h>		/* PATH_MAX */
 #include <stdlib.h>		/* get{env,progname} */
@@ -54,14 +55,34 @@ add_str(uint8_t *shm, size_t shm_pos, const char *str, uint16_t null_len)
 	return shm_pos + null_len;
 }
 
+static uint8_t *
+add_new_region(int bytes)
+{
+	uint8_t		*shm;
+	int		 page_size = getpagesize();
+	int		 page_mask = page_size - 1;
+	int		 aligned_bytes;
+
+	aligned_bytes = ((bytes) + page_mask) & ~page_mask;
+
+	if (ftruncate(shm_fd, shm_len + aligned_bytes) < 0)
+		err(1, "ftruncate from %i to %i", shm_len, shm_len + aligned_bytes);
+
+	shm = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED,
+			shm_fd, shm_len);
+
+	if (shm == MAP_FAILED)
+		err(1, "mmap %i bytes @ %i", bytes, shm_len);
+
+	shm_len += aligned_bytes;
+	return shm;
+}
+
 /*
  * These are written into shared memory, offset 0:
  * - version major and minor
- * - total number of translation units
  * - process id, parent process id, group process id
- * - length of program name
  * - program name
- * - length of current working directory
  * - current working directory
  */
 static void
@@ -84,13 +105,7 @@ write_header()
 	sz += prog_sz;
 	sz += cwd_sz;
 
-	if (ftruncate(shm_fd, sz) < 0)
-		err(1, "ftruncate");
-
-	uint8_t *shm = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
-	if (shm == MAP_FAILED)
-		err(1, "mmap");
-	shm_len = sz;
+	uint8_t *shm = add_new_region(sz);
 
 	size_t shm_pos = 0;
 	shm_pos = add_1(shm, shm_pos, citrun_major);
@@ -106,33 +121,28 @@ write_header()
 	assert(shm_pos == sz);
 }
 
-/*
- * Operates on global shm_fd.
- */
-static int
-get_shm_fd()
+static void
+create_memory_file()
 {
-	char *shm_path;
-
-	assert(shm_fd >= 0);
-
-	if (shm_fd > 0)
-		return shm_fd;
+	assert(shm_fd == 0);
+	assert(shm_len == 0);
 
+#if 0
 	if ((shm_path = getenv("CITRUN_SHMPATH")) == NULL)
 		shm_path = SHM_PATH;
+#endif
 
-	if ((shm_fd = shm_open(shm_path, O_CREAT | O_CLOEXEC | O_RDWR,
-			S_IRUSR | S_IWUSR)) < 0)
-		err(1, "shm_open");
+	/* Existing directory is OK. */
+	if (mkdir("/tmp/citrun", S_IRWXU) && errno != EEXIST)
+		err(1, "mkdir");
 
-	if (init > 0)
-		errx(1, "init > 0!");
-
-	write_header();
+	char shm_path[23];
+	strlcpy(shm_path, "/tmp/citrun/pid.XXXXXX", sizeof(shm_path));
+	if ((shm_fd = mkstemp(shm_path)) == -1)
+		err(1, "mkstemp");
 
 	init++;
-	return shm_fd;
+	write_header();
 }
 
 
@@ -142,7 +152,6 @@ get_shm_fd()
 void
 citrun_node_add(uint8_t node_major, uint8_t node_minor, struct citrun_node *n)
 {
-	int fd;
 	size_t sz = 0;
 	size_t comp_sz, abs_sz;
 	uint8_t *shm;
@@ -150,11 +159,11 @@ citrun_node_add(uint8_t node_major, uint8_t node_minor, struct citrun_node *n)
 
 	if (node_major != citrun_major || node_minor != citrun_minor) {
 		errx(1, "libcitrun %i.%i: incompatible node version %i.%i",
-			citrun_major, citrun_minor,
-			node_major, node_minor);
+			citrun_major, citrun_minor, node_major, node_minor);
 	}
 
-	fd = get_shm_fd();
+	if (!init)
+		create_memory_file();
 
 	comp_sz = strnlen(n->comp_file_path, PATH_MAX) + 1;
 	abs_sz = strnlen(n->abs_file_path, PATH_MAX) + 1;
@@ -165,14 +174,7 @@ citrun_node_add(uint8_t node_major, uint8_t node_minor, struct citrun_node *n)
 	sz += abs_sz;
 	sz += n->size * sizeof(uint64_t);
 
-	/* Extend the file for new node + line counts. */
-	if (ftruncate(fd, shm_len + sz) < 0)
-		err(1, "ftruncate");
-
-	shm = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, shm_len);
-	if (shm == MAP_FAILED)
-		err(1, "mmap");
-	shm_len += sz;
+	shm = add_new_region(sz);
 
 	/* Skip past the 'ready' bit location. */
 	size_t ready_bit = shm_pos;