util.c (4306B)
1#define _GNU_SOURCE 2 3#include "test/util.h" 4 5#include <sys/types.h> 6#include <sys/mman.h> 7#include <dirent.h> 8#include <pthread.h> 9#include <err.h> 10#include <sched.h> 11#include <string.h> 12#include <stdio.h> 13#include <stdint.h> 14#include <stdlib.h> 15 16void 17hexdump(void *data, int len) 18{ 19 int i; 20 21 for (i = 0; i < len; i++) { 22 if (i % 16 == 0 && i) 23 printf("\n"); 24 printf("%02X ", *(uint8_t *)(data + i)); 25 } 26 printf("\n"); 27} 28 29bool 30pin_process(pid_t pid, int cpu, bool assert) 31{ 32 cpu_set_t cpuset; 33 int ret; 34 35 CPU_ZERO(&cpuset); 36 CPU_SET(cpu, &cpuset); 37 ret = sched_setaffinity(pid, sizeof(cpu_set_t), &cpuset); 38 if (ret == -1) { 39 if (assert) err(1, "sched_setaffinity"); 40 return false; 41 } 42 43 return true; 44} 45 46int 47read_stat_core(pid_t pid) 48{ 49 char path[256]; 50 char line[2048]; 51 FILE *file; 52 char *p; 53 int i, cpu; 54 55 snprintf(path, sizeof(path), "/proc/%u/stat", pid); 56 file = fopen(path, "r"); 57 if (!file) return -1; 58 59 if (!fgets(line, sizeof(line), file)) 60 err(1, "read stat"); 61 62 p = line; 63 for (i = 0; i < 38 && (p = strchr(p, ' ')); i++) 64 p += 1; 65 66 if (!p) errx(1, "stat format"); 67 cpu = atoi(p); 68 69 fclose(file); 70 71 return cpu; 72} 73 74pid_t 75pgrep(const char *bin) 76{ 77 char path[PATH_MAX]; 78 char buf[PATH_MAX]; 79 struct dirent *ent; 80 char *cmp; 81 FILE *f; 82 DIR *dir; 83 pid_t pid; 84 85 dir = opendir("/proc"); 86 if (!dir) err(1, "opendir"); 87 88 pid = 0; 89 while (!pid && (ent = readdir(dir))) { 90 snprintf(path, sizeof(path), "/proc/%s/cmdline", ent->d_name); 91 f = fopen(path, "rb"); 92 if (!f) continue; 93 memset(buf, 0, sizeof(buf)); 94 fread(buf, 1, sizeof(buf), f); 95 if ((cmp = strrchr(buf, '/'))) 96 cmp += 1; 97 else 98 cmp = buf; 99 if (!strcmp(cmp, bin)) 100 pid = atoi(ent->d_name); 101 fclose(f); 102 } 103 104 closedir(dir); 105 106 return pid; 107} 108 109void 110print_counts(uint8_t *counts) 111{ 112 int i; 113 114 for (i = 0; i < 64; i++) { 115 if (i % 16 == 0 && i) 116 printf("\n"); 117 if (counts[i] == 1) 118 printf("\x1b[38;5;88m"); 119 else if (counts[i] > 1) 120 printf("\x1b[38;5;196m"); 121 printf("%2i ", i); 122 if (counts[i] > 0) 123 printf("\x1b[0m"); 124 } 125 printf("\n"); 126} 127 128void 129print_counts_raw(uint8_t *counts) 130{ 131 int i; 132 133 for (i = 0; i < 64; i++) { 134 if (i % 16 == 0 && i) 135 printf("\n"); 136 if (counts[i] == 1) 137 printf("\x1b[38;5;88m"); 138 else if (counts[i] > 1) 139 printf("\x1b[38;5;196m"); 140 printf("%02X ", (uint8_t) counts[i]); 141 if (counts[i] > 0) 142 printf("\x1b[0m"); 143 } 144 printf("\n"); 145} 146 147struct ipc * 148ipc_alloc(void) 149{ 150 pthread_mutexattr_t mutex_attr; 151 pthread_condattr_t cond_attr; 152 struct ipc *ipc; 153 154 pthread_condattr_init(&cond_attr); 155 pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); 156 157 pthread_mutexattr_init(&mutex_attr); 158 pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); 159 160 ipc = mmap(NULL, sizeof(struct ipc), PROT_READ | PROT_WRITE, 161 MAP_SHARED | MAP_ANONYMOUS, -1, 0); 162 if (ipc == MAP_FAILED) err(1, "mmap"); 163 164 pthread_mutex_init(&ipc->lock, &mutex_attr); 165 166 pthread_cond_init(&ipc->sig_parent, &cond_attr); 167 ipc->has_sig_parent = false; 168 169 pthread_cond_init(&ipc->sig_child, &cond_attr); 170 ipc->has_sig_child = false; 171 172 ipc->init = true; 173 174 return ipc; 175} 176 177void 178ipc_free(struct ipc *ipc) 179{ 180 if (ipc->init) { 181 pthread_mutex_destroy(&ipc->lock); 182 pthread_cond_destroy(&ipc->sig_parent); 183 pthread_cond_destroy(&ipc->sig_child); 184 ipc->init = false; 185 } 186 munmap(ipc, sizeof(ipc)); 187} 188 189void 190ipc_signal_parent(struct ipc *ipc) 191{ 192 if (!ipc->init) errx(1, "ipc deinit"); 193 pthread_mutex_lock(&ipc->lock); 194 if (!ipc->has_sig_child) 195 pthread_cond_signal(&ipc->sig_child); 196 ipc->has_sig_child = true; 197 pthread_mutex_unlock(&ipc->lock); 198} 199 200void 201ipc_wait_child(struct ipc *ipc) 202{ 203 if (!ipc->init) errx(1, "ipc deinit"); 204 pthread_mutex_lock(&ipc->lock); 205 while (!ipc->has_sig_child) 206 pthread_cond_wait(&ipc->sig_child, &ipc->lock); 207 ipc->has_sig_child = false; 208 pthread_mutex_unlock(&ipc->lock); 209} 210 211void 212ipc_signal_child(struct ipc *ipc) 213{ 214 if (!ipc->init) errx(1, "ipc deinit"); 215 pthread_mutex_lock(&ipc->lock); 216 if (!ipc->has_sig_parent) 217 pthread_cond_signal(&ipc->sig_parent); 218 ipc->has_sig_parent = true; 219 pthread_mutex_unlock(&ipc->lock); 220} 221 222void 223ipc_wait_parent(struct ipc *ipc) 224{ 225 if (!ipc->init) errx(1, "ipc deinit"); 226 pthread_mutex_lock(&ipc->lock); 227 while (!ipc->has_sig_parent) 228 pthread_cond_wait(&ipc->sig_parent, &ipc->lock); 229 ipc->has_sig_parent = false; 230 pthread_mutex_unlock(&ipc->lock); 231} 232