commit 3ac0a43822a62c4f72e326059fe60df7032dd3f9
parent 95a73422904fbe77f511cc7f1e4f2a7f326d35a7
Author: Kyle Milz <kyle@0x30.net>
Date: Sat, 24 Sep 2016 21:13:43 -0600
src/rt: add comments and improve naming
Diffstat:
M | src/rt.c | | | 113 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
1 file changed, 70 insertions(+), 43 deletions(-)
diff --git a/src/rt.c b/src/rt.c
@@ -58,8 +58,14 @@ add_str(uint8_t *shm, size_t shm_pos, const char *str, uint16_t len)
return shm_pos + len;
}
+/*
+ * Extends the memory mapping of shm_fd some number of bytes rounded up to the
+ * next page size.
+ * Exits on error, returns a pointer to the beginning of the extended memory
+ * region on success.
+ */
static uint8_t *
-add_new_region(int bytes)
+shm_extend(int bytes)
{
uint8_t *shm;
int page_size = getpagesize();
@@ -68,32 +74,39 @@ add_new_region(int bytes)
aligned_bytes = ((bytes) + page_mask) & ~page_mask;
+ /* Increase the length of the file descriptor. */
if (ftruncate(shm_fd, shm_len + aligned_bytes) < 0)
err(1, "ftruncate from %zu to %zu", shm_len, shm_len + aligned_bytes);
+ /* Increase the size of the memory mapping. */
shm = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED,
shm_fd, shm_len);
if (shm == MAP_FAILED)
err(1, "mmap %i bytes @ %zu", bytes, shm_len);
+ /* Increase internal length field. */
shm_len += aligned_bytes;
return shm;
}
/*
- * These are written into shared memory, offset 0:
+ * Add a header region to a newly created shared memory file.
+ * The header contains:
* - version major and minor
* - process id, parent process id, group process id
* - program name
* - current working directory
+ * Exits or asserts on error.
*/
static void
-write_header()
+shm_add_header()
{
char *cwd_buf;
const char *progname;
- size_t sz = 0;
+ uint8_t *shm;
+ size_t sz;
+ size_t shm_pos;
uint16_t prog_sz, cwd_sz;
progname = getprogname();
@@ -103,6 +116,7 @@ write_header()
prog_sz = strnlen(progname, PATH_MAX);
cwd_sz = strnlen(cwd_buf, PATH_MAX);
+ sz = 0;
sz += sizeof(uint8_t) * 2;
sz += sizeof(uint32_t) * 3;
sz += sizeof(prog_sz);
@@ -110,9 +124,9 @@ write_header()
sz += sizeof(cwd_sz);
sz += cwd_sz;
- uint8_t *shm = add_new_region(sz);
+ shm = shm_extend(sz);
- size_t shm_pos = 0;
+ shm_pos = 0;
shm_pos = add_1(shm, shm_pos, citrun_major);
shm_pos = add_1(shm, shm_pos, citrun_minor);
@@ -126,46 +140,23 @@ write_header()
assert(shm_pos == sz);
}
+/*
+ * Adds a new memory region for a given citrun_node.
+ * The data format is described in the instrumentation header generation code.
+ * Exits on failure.
+ */
static void
-create_memory_file()
-{
- char memfile_path[23];
- char *template = "/tmp/citrun/XXXXXXXXXX";
- char *process_dir = "/tmp/citrun";
-
- assert(shm_fd == 0);
- assert(shm_len == 0);
-
- if (getenv("CITRUN_TOOLS") != NULL) {
- if ((shm_fd = open("procfile.shm", O_RDWR | O_CREAT,
- S_IRUSR | S_IWUSR)) == -1)
- err(1, "open");
- } else {
- /* Existing directory is OK. */
- if (mkdir(process_dir, S_IRWXU) && errno != EEXIST)
- err(1, "mkdir '%s'", process_dir);
-
- strlcpy(memfile_path, template, sizeof(memfile_path));
-
- if ((shm_fd = mkstemp(memfile_path)) == -1)
- err(1, "mkstemp");
- }
-
- init++;
- write_header();
-}
-
-static void
-node_add(struct citrun_node *n)
+shm_add_node(struct citrun_node *n)
{
- size_t sz = 0;
- uint16_t comp_sz, abs_sz;
- uint8_t *shm;
- size_t shm_pos = 0;
+ uint8_t *shm;
+ size_t sz;
+ size_t shm_pos;
+ uint16_t comp_sz, abs_sz;
comp_sz = strnlen(n->comp_file_path, PATH_MAX);
abs_sz = strnlen(n->abs_file_path, PATH_MAX);
+ sz = 0;
sz += sizeof(uint32_t);
sz += sizeof(comp_sz);
sz += comp_sz;
@@ -173,8 +164,9 @@ node_add(struct citrun_node *n)
sz += abs_sz;
sz += n->size * sizeof(uint64_t);
- shm = add_new_region(sz);
+ shm = shm_extend(sz);
+ shm_pos = 0;
shm_pos = add_4(shm, shm_pos, n->size);
shm_pos = add_str(shm, shm_pos, n->comp_file_path, comp_sz);
shm_pos = add_str(shm, shm_pos, n->abs_file_path, abs_sz);
@@ -186,6 +178,41 @@ node_add(struct citrun_node *n)
}
/*
+ * Usually opens a file descriptor with a random file name in a known directory.
+ * Should only ever be called once per process. Adds a header to the created
+ * file containing program meta information.
+ * Exits on failure.
+ */
+static void
+shm_create()
+{
+ char memfile_path[23];
+ char *template = "/tmp/citrun/XXXXXXXXXX";
+ char *process_dir = "/tmp/citrun";
+
+ assert(shm_fd == 0);
+ assert(shm_len == 0);
+
+ if (getenv("CITRUN_TOOLS") != NULL) {
+ if ((shm_fd = open("procfile.shm", O_RDWR | O_CREAT,
+ S_IRUSR | S_IWUSR)) == -1)
+ err(1, "open");
+ } else {
+ /* Existing directory is OK. */
+ if (mkdir(process_dir, S_IRWXU) && errno != EEXIST)
+ err(1, "mkdir '%s'", process_dir);
+
+ strlcpy(memfile_path, template, sizeof(memfile_path));
+
+ if ((shm_fd = mkstemp(memfile_path)) == -1)
+ err(1, "mkstemp");
+ }
+
+ init++;
+ shm_add_header();
+}
+
+/*
* Public interface: Add a node to shared memory.
*/
void
@@ -200,7 +227,7 @@ citrun_node_add(uint8_t node_major, uint8_t node_minor, struct citrun_node *n)
citrun_major, citrun_minor, node_major, node_minor);
if (!init)
- create_memory_file();
+ shm_create();
- node_add(n);
+ shm_add_node(n);
}