diff options
author | Vito Caputo <vcaputo@gnugeneration.com> | 2017-03-21 04:08:55 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@gnugeneration.com> | 2017-03-21 04:40:56 -0700 |
commit | ee8c198a3c6cbc7bb877fdc2378ef6a8e758032e (patch) | |
tree | f77313c28acc97e4eae93078fddecef4a97f7775 /src | |
parent | 12823bbb015269658217b20950568dec58d78692 (diff) |
libvmon: style cleanups
Bring libvmon code inline with the direction vwm has headed in terms
of coding style. Entirely mechanical changes with one exception
replacing a free()/=NULL idiom with try_free().
Diffstat (limited to 'src')
-rw-r--r-- | src/libvmon/defs/_begin.def | 408 | ||||
-rw-r--r-- | src/libvmon/vmon.c | 539 |
2 files changed, 437 insertions, 510 deletions
diff --git a/src/libvmon/defs/_begin.def b/src/libvmon/defs/_begin.def index 047fd4d..f6b441a 100644 --- a/src/libvmon/defs/_begin.def +++ b/src/libvmon/defs/_begin.def @@ -174,28 +174,28 @@ * names etc. */ #define vmon_datum_str(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case VMON_PARSER_DELIM:\ - /* store accumulated string, reset tmp, and advance */\ - if(*store)->_name) {\ - if( strncmp((*store)->name, _array, var_array_len) ||\ - (*store)->name[var_array_len] != '\0') {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - }\ - free((*store)->name);\ - } else {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ + switch (input) {\ + case VMON_PARSER_DELIM:\ + /* store accumulated string, reset tmp, and advance */\ + if ((*store)->_name) {\ + if ( strncmp((*store)->name, _array, var_array_len) ||\ + (*store)->name[var_array_len] != '\0') {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ }\ - (*store)->_name = strndup(var_array, var_array_len);\ - var_array_len = 0;\ - state++;\ - break;\ - default:\ - /* accumulate string */\ - var_array[var_array_len++] = input;\ - break;\ + free((*store)->name);\ + } else {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + }\ + (*store)->_name = strndup(var_array, var_array_len);\ + var_array_len = 0;\ + state++;\ + break;\ + default:\ + /* accumulate string */\ + var_array[var_array_len++] = input;\ + break;\ }\ break; @@ -204,7 +204,7 @@ break; #define vmon_datum_char(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - if((*store)->_name != input) {\ + if ((*store)->_name != input) {\ BITSET((*store)->changed, VMON_ ## _sym);\ changes++;\ (*store)->_name = input;\ @@ -218,159 +218,153 @@ break; #define vmon_datum_int(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '-':\ - /* TODO: we don't verify the '-' is leading... */\ - var_isneg = 1;\ - break;\ - case '0' ... '9':\ - var_int *= 10;\ - var_int += input - '0';\ - break;\ - default:\ - if(var_isneg) {\ - var_int = -var_int;\ - var_isneg = 0;\ - }\ - if((*store)->_name != var_int) {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - (*store)->_name = var_int;\ - }\ - var_int = 0;\ - state++;\ - break;\ + switch (input) {\ + case '-':\ + /* TODO: we don't verify the '-' is leading... */\ + var_isneg = 1;\ + break;\ + case '0' ... '9':\ + var_int *= 10;\ + var_int += input - '0';\ + break;\ + default:\ + if (var_isneg) {\ + var_int = -var_int;\ + var_isneg = 0;\ + }\ + if ((*store)->_name != var_int) {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + (*store)->_name = var_int;\ + }\ + var_int = 0;\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_datum_uint(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - var_uint *= 10;\ - var_uint += input - '0';\ - break;\ - default:\ - if((*store)->_name != var_uint) {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - (*store)->_name = var_uint;\ - }\ - var_uint = 0;\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + var_uint *= 10;\ + var_uint += input - '0';\ + break;\ + default:\ + if ((*store)->_name != var_uint) {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + (*store)->_name = var_uint;\ + }\ + var_uint = 0;\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_datum_ulong(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - var_ulong *= 10;\ - var_ulong += input - '0';\ - break;\ - default:\ - if((*store)->_name != var_ulong) {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - (*store)->_name = var_ulong;\ - }\ - var_ulong = 0;\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + var_ulong *= 10;\ + var_ulong += input - '0';\ + break;\ + default:\ + if ((*store)->_name != var_ulong) {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + (*store)->_name = var_ulong;\ + }\ + var_ulong = 0;\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_datum_ulonglong(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - var_ulonglong *= 10;\ - var_ulonglong += input - '0';\ - break;\ - default:\ - if((*store)->_name != var_ulonglong) {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - (*store)->_name = var_ulonglong;\ - }\ - var_ulonglong = 0;\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + var_ulonglong *= 10;\ + var_ulonglong += input - '0';\ + break;\ + default:\ + if ((*store)->_name != var_ulonglong) {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + (*store)->_name = var_ulonglong;\ + }\ + var_ulonglong = 0;\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_datum_long(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '-':\ - /* TODO: we dont verify the '-' is leading... */\ - var_isneg = 1;\ - break;\ - case '0' ... '9':\ - var_long *= 10;\ - var_long += input - '0';\ - break;\ - default:\ - if(var_isneg) {\ - var_long = -var_long;\ - var_isneg = 0;\ - }\ - if((*store)->_name != var_long) {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - (*store)->_name = var_long;\ - }\ - var_long = 0;\ - state++;\ - break;\ + switch (input) {\ + case '-':\ + /* TODO: we dont verify the '-' is leading... */\ + var_isneg = 1;\ + break;\ + case '0' ... '9':\ + var_long *= 10;\ + var_long += input - '0';\ + break;\ + default:\ + if (var_isneg) {\ + var_long = -var_long;\ + var_isneg = 0;\ + }\ + if ((*store)->_name != var_long) {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + (*store)->_name = var_long;\ + }\ + var_long = 0;\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_datum_longlong(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '-':\ - /* TODO: we dont verify the '-' is leading... */\ - var_isneg = 1;\ - break;\ - case '0' ... '9':\ - var_longlong *= 10;\ - var_longlong += input - '0';\ - break;\ - default:\ - if(var_isneg) {\ - var_longlong = -var_longlong;\ - var_isneg = 0;\ - }\ - if((*store)->_name != var_longlong) {\ - BITSET((*store)->changed, VMON_ ## _sym);\ - changes++;\ - (*store)->_name = var_longlong;\ - }\ - var_longlong = 0;\ - state++;\ - break;\ + switch (input) {\ + case '-':\ + /* TODO: we dont verify the '-' is leading... */\ + var_isneg = 1;\ + break;\ + case '0' ... '9':\ + var_longlong *= 10;\ + var_longlong += input - '0';\ + break;\ + default:\ + if (var_isneg) {\ + var_longlong = -var_longlong;\ + var_isneg = 0;\ + }\ + if ((*store)->_name != var_longlong) {\ + BITSET((*store)->changed, VMON_ ## _sym);\ + changes++;\ + (*store)->_name = var_longlong;\ + }\ + var_longlong = 0;\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; /* parse but simply skip omitted fields, advance on the delimiter */ #define vmon_omit_n(_n, _sym, _desc) case VMON_PARSER_STATE_ ## _sym:\ var_int++;\ - if(var_int >= _n) {\ + if (var_int >= _n) {\ var_int = 0;\ state++;\ }\ @@ -379,14 +373,14 @@ #define vmon_omit_literal(_lit, _sym) case VMON_PARSER_STATE_ ## _sym:\ /* TODO make this actually match the literal, for now we skip the length. */ \ var_int++;\ - if(var_int >= (sizeof(_lit) - 1)) {\ + if (var_int >= (sizeof(_lit) - 1)) {\ var_int = 0;\ state++;\ }\ break; #define vmon_omit_run(_char, _sym) case VMON_PARSER_STATE_ ## _sym:\ - if(input != _char) {\ + if (input != _char) {\ state++;\ /* XXX: we fall-through to the next case because this byte belongs to the next state */\ } else {\ @@ -395,14 +389,14 @@ #define vmon_omit_str(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - if(input == VMON_PARSER_DELIM) {\ + if (input == VMON_PARSER_DELIM) {\ state++;\ } else {\ break;\ } #define vmon_omit_str_array(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - if(input == VMON_PARSER_DELIM) {\ + if (input == VMON_PARSER_DELIM) {\ state++;\ } else {\ break;\ @@ -413,92 +407,86 @@ break; #define vmon_omit_char_array(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - if(input == VMON_PARSER_DELIM) {\ + if (input == VMON_PARSER_DELIM) {\ state++;\ } else {\ break;\ } #define vmon_omit_int(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - case '-':\ - break;\ - default:\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + case '-':\ + break;\ + default:\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ break;\ - } #define vmon_omit_uint(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - break;\ - default:\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + break;\ + default:\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_omit_ulong(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - break;\ - default:\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + break;\ + default:\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_omit_ulonglong(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - break;\ - default:\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + break;\ + default:\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_omit_long(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - case '-':\ - break;\ - default:\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + case '-':\ + break;\ + default:\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #define vmon_omit_longlong(_name, _sym, _label, _desc) case VMON_PARSER_STATE_ ## _sym:\ - switch(input) {\ - case '0' ... '9':\ - case '-':\ - break;\ - default:\ - state++;\ - break;\ + switch (input) {\ + case '0' ... '9':\ + case '-':\ + break;\ + default:\ + state++;\ + break;\ }\ - if(state == VMON_PARSER_STATE_ ## _sym) {\ + if (state == VMON_PARSER_STATE_ ## _sym)\ /* we want to fall-through when the state advances */\ - break;\ - } + break; #endif diff --git a/src/libvmon/vmon.c b/src/libvmon/vmon.c index 1995228..e7936b5 100644 --- a/src/libvmon/vmon.c +++ b/src/libvmon/vmon.c @@ -50,7 +50,7 @@ typedef enum _sample_ret_t { /* some private convenience functions */ static void try_free(void **ptr) { - if((*ptr)) { + if ((*ptr)) { free((*ptr)); (*ptr) = NULL; } @@ -59,7 +59,7 @@ static void try_free(void **ptr) static void try_close(int *fd) { - if((*fd) != -1) { + if ((*fd) != -1) { close((*fd)); (*fd) = -1; } @@ -68,7 +68,7 @@ static void try_close(int *fd) static void try_closedir(DIR **dir) { - if((*dir)) { + if ((*dir)) { closedir((*dir)); (*dir) = NULL; } @@ -78,7 +78,7 @@ static void try_closedir(DIR **dir) /* these have been wrapped to suppress syscall overhead when we have a bad file descriptor without cluttering the samplers with checks */ static off_t try_lseek(int fd, off_t offset, int whence) { - if(fd != -1) { + if (fd != -1) { return lseek(fd, offset, whence); } else { errno = EBADF; @@ -89,7 +89,7 @@ static off_t try_lseek(int fd, off_t offset, int whence) static ssize_t try_read(int fd, void *buf, size_t count) { - if(fd != -1) { + if (fd != -1) { return read(fd, buf, count); } else { errno = EBADF; @@ -105,22 +105,22 @@ static void memcmpcpy(void *dest, const void *src, size_t n, char *changed, int size_t i = 0; /* if the changed bit is set on entry we don't execute the comparison-copy */ - if(!BITTEST(changed, changed_pos)) { + if (!BITTEST(changed, changed_pos)) { /* a simple slow compare and copy loop, break out if we've found a change */ /* XXX TODO: an obvious optimization would be to compare and copy words at a time... */ - for(; i < n; i++) { - if(((char *)dest)[i] != ((char *)src)[i]) { + for (; i < n; i++) { + if (((char *)dest)[i] != ((char *)src)[i]) { BITSET(changed, changed_pos); break; } + ((char *)dest)[i] = ((char *)src)[i]; } } /* memcpy whatever remains */ - if(n - i) { + if (n - i) memcpy(&((char *)dest)[i], &((char *)src)[i], n - i); - } } @@ -135,13 +135,12 @@ static char * load_contents_fd(vmon_t *vmon, vmon_char_array_t *array, int fd, v int total = 0, len, alloc_len = array->alloc_len; char *alloc = array->array, *tmp; - while((len = read(fd, vmon->buf, sizeof(vmon->buf))) > 0) { - if(total + len > alloc_len) { + while ((len = read(fd, vmon->buf, sizeof(vmon->buf))) > 0) { + if (total + len > alloc_len) { /* realloc to accomodate the new total */ tmp = realloc(alloc, total + len); - if(!tmp) { + if (!tmp) return NULL; - } alloc_len = total + len; alloc = tmp; @@ -156,11 +155,10 @@ static char * load_contents_fd(vmon_t *vmon, vmon_char_array_t *array, int fd, v array->alloc_len = alloc_len; /* if we read something or didn't encounter an error, store the new total */ - if(total || (len == 0 && !(flags & LOAD_FLAGS_NOTRUNCATE))) { + if (total || (len == 0 && !(flags & LOAD_FLAGS_NOTRUNCATE))) { /* if the new length differs ensure the changed bit is set */ - if(array->len != total) { + if (array->len != total) BITSET(changed, changed_pos); - } array->len = total; } @@ -196,9 +194,8 @@ static DIR * opendirf(vmon_t *vmon, DIR *dir, char *fmt, ...) va_end(va_arg); fd = openat(dirfd(dir), vmon->buf, O_RDONLY); - if(fd == -1) { + if (fd == -1) return NULL; - } return fdopendir(fd); } @@ -210,9 +207,8 @@ static int grow_array(vmon_char_array_t *array, int amount) char *tmp; tmp = realloc(array->array, array->alloc_len + amount); - if(!tmp) { + if (!tmp) return 0; - } array->alloc_len += amount; array->array = tmp; @@ -233,17 +229,15 @@ static char * readlinkf(vmon_t *vmon, vmon_char_array_t *array, DIR *dir, char * vsnprintf(vmon->buf, sizeof(vmon->buf), fmt, va_arg); va_end(va_arg); - if(!array->array && !grow_array(array, READLINKF_GROWINIT)) { + if (!array->array && !grow_array(array, READLINKF_GROWINIT)) goto _fail; - } do { len = readlinkat(dirfd(dir), vmon->buf, array->array, (array->alloc_len - 1)); - } while(len != -1 && len == (array->alloc_len - 1) && (len = grow_array(array, READLINKF_GROWBY))); + } while (len != -1 && len == (array->alloc_len - 1) && (len = grow_array(array, READLINKF_GROWBY))); - if(len <= 0) { + if (len <= 0) goto _fail; - } array->len = len; array->array[array->len] = '\0'; @@ -273,7 +267,7 @@ static sample_ret_t proc_sample_stat(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_ #define VMON_PREPARE_PARSER #include "defs/proc_stat.def" - if(!proc) { /* dtor */ + if (!proc) { /* dtor */ try_close(&(*store)->comm_fd); try_free((void **)&(*store)->comm); try_close(&(*store)->cmdline_fd); @@ -286,11 +280,11 @@ static sample_ret_t proc_sample_stat(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_ } _retry: - if(!(*store)) { /* ctor */ + if (!(*store)) { /* ctor */ *store = calloc(1, sizeof(vmon_proc_stat_t)); - if(proc->is_thread) { + if (proc->is_thread) { (*store)->comm_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/task/%i/comm", proc->pid, proc->pid); (*store)->cmdline_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/task/%i/cmdline", proc->pid, proc->pid); (*store)->wchan_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/task/%i/wchan", proc->pid, proc->pid); @@ -320,21 +314,20 @@ _retry: /* /proc/$pid/cmdline */ load_contents_fd(vmon, &(*store)->cmdline, (*store)->cmdline_fd, LOAD_FLAGS_NOTRUNCATE, (*store)->changed, VMON_PROC_STAT_CMDLINE); - for(prev_argc = (*store)->argc, (*store)->argc = 0, i = 0; i < (*store)->cmdline.len; i++) { - if(!(*store)->cmdline.array[i]) { + for (prev_argc = (*store)->argc, (*store)->argc = 0, i = 0; i < (*store)->cmdline.len; i++) { + if (!(*store)->cmdline.array[i]) (*store)->argc++; - } } /* if the cmdline has changed, allocate argv array and store ptrs to the fields within it */ - if(BITTEST((*store)->changed, VMON_PROC_STAT_CMDLINE)) { - if(prev_argc != (*store)->argc) { + if (BITTEST((*store)->changed, VMON_PROC_STAT_CMDLINE)) { + if (prev_argc != (*store)->argc) { try_free((void **)&(*store)->argv); /* XXX could realloc */ (*store)->argv = malloc((*store)->argc * sizeof(char *)); } - for(argn = 0, arg = (*store)->cmdline.array, i = 0; i < (*store)->cmdline.len; i++) { - if(!(*store)->cmdline.array[i]) { + for (argn = 0, arg = (*store)->cmdline.array, i = 0; i < (*store)->cmdline.len; i++) { + if (!(*store)->cmdline.array[i]) { (*store)->argv[argn++] = arg; arg = &(*store)->cmdline.array[i + 1]; } @@ -345,25 +338,24 @@ _retry: load_contents_fd(vmon, &(*store)->wchan, (*store)->wchan_fd, LOAD_FLAGS_NOTRUNCATE, (*store)->changed, VMON_PROC_STAT_WCHAN); /* /proc/$pid/exe */ - if((*store)->cmdline.len) { /* kernel threads have no cmdline, and always fail readlinkf() on exe, skip readlinking the exe for them using this heuristic */ + if ((*store)->cmdline.len) /* kernel threads have no cmdline, and always fail readlinkf() on exe, skip readlinking the exe for them using this heuristic */ readlinkf(vmon, &(*store)->exe, vmon->proc_dir, "%i/exe", proc->pid); - } /* XXX TODO: there's a race between discovering comm_len from /proc/$pid/comm and applying it in the parsing of /proc/$pid/stat, detect the race * scenario and retry the sample when detected by goto _retry */ /* read in stat and parse it assigning the stat members accordingly */ - while((len = try_read((*store)->stat_fd, vmon->buf, sizeof(vmon->buf))) > 0) { - for(i = 0; i < len; i++) { + while ((len = try_read((*store)->stat_fd, vmon->buf, sizeof(vmon->buf))) > 0) { + for (i = 0; i < len; i++) { /* parse the fields from the file, stepping through... */ input = vmon->buf[i]; - switch(state) { + switch (state) { #define VMON_PARSER_DELIM ' ' /* TODO XXX eliminate the need for this, I want the .def's to include all the data format knowledge */ #define VMON_IMPLEMENT_PARSER #include "defs/proc_stat.def" - default: - /* we're finished parsing once we've fallen off the end of the symbols */ - break; + default: + /* we're finished parsing once we've fallen off the end of the symbols */ + break; } } } @@ -380,17 +372,16 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo vmon_proc_t *tmp, *_tmp; list_head_t *cur, *start; - if(!proc) { /* dtor */ + if (!proc) { /* dtor */ try_close(&(*store)->children_fd); return DTOR_FREE; } - if(proc->is_thread) { /* don't follow children of threads */ + if (proc->is_thread) /* don't follow children of threads */ return SAMPLE_UNCHANGED; - } - if(!(*store)) { /* implicit ctor on first sample */ + if (!(*store)) { /* implicit ctor on first sample */ *store = calloc(1, sizeof(vmon_proc_follow_children_t)); (*store)->children_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/task/%i/children", proc->pid, proc->pid); @@ -400,7 +391,7 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo /* unmonitor stale children on entry, this concludes the two-phase removal of a process */ list_for_each_entry_safe(tmp, _tmp, &proc->children, siblings) { - if(tmp->is_stale) { + if (tmp->is_stale) { vmon_proc_unmonitor(vmon, tmp, NULL, NULL); } #ifdef _MOVE_STALE_TO_FRONT @@ -411,7 +402,7 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo } /* if we have a parent, and our parent has become stale, ensure this, the child, becomes stale as well */ - if(proc->parent && proc->parent->is_stale) { + if (proc->parent && proc->parent->is_stale) { proc->is_stale = 1; proc->parent->children_changed = 1; return SAMPLE_CHANGED; @@ -419,40 +410,40 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo /* maintain our awareness of children, if we detect a new child initiate monitoring for it, existing children get their generation number updated */ start = &proc->children; - while((len = try_read((*store)->children_fd, vmon->buf, sizeof(vmon->buf))) > 0) { - for(i = 0; i < len; i++) { - switch(vmon->buf[i]) { - case '0' ... '9': - /* PID component, accumulate it */ - child_pid *= 10; - child_pid += (vmon->buf[i] - '0'); - break; + while ((len = try_read((*store)->children_fd, vmon->buf, sizeof(vmon->buf))) > 0) { + for (i = 0; i < len; i++) { + switch (vmon->buf[i]) { + case '0' ... '9': + /* PID component, accumulate it */ + child_pid *= 10; + child_pid += (vmon->buf[i] - '0'); + break; - case ' ': - /* separator, terminates a PID, search for it in the childrens list */ - found = 0; - list_for_each(cur, start) { - if(list_entry(cur, vmon_proc_t, siblings)->pid == child_pid) { - /* found the child already monitored, update its generation number and stop searching */ - tmp = list_entry(cur, vmon_proc_t, siblings); - tmp->generation = vmon->generation; - found = 1; - tmp->is_new = 0; - break; - } + case ' ': + /* separator, terminates a PID, search for it in the childrens list */ + found = 0; + list_for_each(cur, start) { + if (list_entry(cur, vmon_proc_t, siblings)->pid == child_pid) { + /* found the child already monitored, update its generation number and stop searching */ + tmp = list_entry(cur, vmon_proc_t, siblings); + tmp->generation = vmon->generation; + found = 1; + tmp->is_new = 0; + break; } + } - if(found || (tmp = vmon_proc_monitor(vmon, proc, child_pid, proc->wants, NULL, NULL))) { - /* position the process in the siblings list, and update the start */ - /* move to front breaks vwm, we rely on the stale processes maintaining their position! maybe make it an option to vmon_init() since it can be a useful optimization. */ + if (found || (tmp = vmon_proc_monitor(vmon, proc, child_pid, proc->wants, NULL, NULL))) { + /* position the process in the siblings list, and update the start */ + /* move to front breaks vwm, we rely on the stale processes maintaining their position! maybe make it an option to vmon_init() since it can be a useful optimization. */ #ifdef _MOVE_STALE_TO_FRONT - list_move_tail(&tmp->siblings, start); + list_move_tail(&tmp->siblings, start); #endif - start = &tmp->siblings; - } /* else { vmon_proc_monitor failed just move on } */ + start = &tmp->siblings; + } /* else { vmon_proc_monitor failed just move on } */ - child_pid = 0; - break; + child_pid = 0; + break; } } } @@ -460,7 +451,7 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo /* look for children which seem to no longer exist (found by stale generation numbers) and queue them for unmonitoring, flag this as a children change too */ found = 0; list_for_each_entry(tmp, &proc->children, siblings) { - if(tmp->generation != vmon->generation) { + if (tmp->generation != vmon->generation) { /* set children not found to stale status so the caller can respond and on our next sample invocation we will unmonitor them */ found = tmp->is_stale = 1; } @@ -473,8 +464,8 @@ static int proc_follow_children(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follo } /* XXX TODO: does it makes sense for shit to happen here? */ - if(found) { - if(proc->parent) { + if (found) { + if (proc->parent) { proc->parent->children_changed = 1; } else { vmon->processes_changed = 1; @@ -494,39 +485,36 @@ static int proc_follow_threads(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follow vmon_proc_t *tmp, *_tmp; int found; - if(!proc) { /* dtor */ + if (!proc) { /* dtor */ try_closedir(&(*store)->task_dir); return DTOR_FREE; } - if(proc->is_thread) { /* bypass following the threads of threads */ + if (proc->is_thread) /* bypass following the threads of threads */ return SAMPLE_UNCHANGED; - } - if(!proc->stores || !proc->stores[VMON_STORE_PROC_STAT] || (((vmon_proc_stat_t *)proc->stores[VMON_STORE_PROC_STAT])->num_threads <= 1 && list_empty(&proc->threads))) { + if (!proc->stores || !proc->stores[VMON_STORE_PROC_STAT] || (((vmon_proc_stat_t *)proc->stores[VMON_STORE_PROC_STAT])->num_threads <= 1 && list_empty(&proc->threads))) /* bypass following of threads if we either can't determine the number from the proc stat sample or if the sample says there's 1 or less (and an empty threads list, handling stale exited threads) */ /* XXX I'm not sure if this is always the right thing to do, there may be some situations where one could play games with clone() directly * and escape the monitoring library with a lone thread having had the main thread exit, leaving the count at 1 while having a process * descriptor distinguished from the single thread XXX */ return SAMPLE_UNCHANGED; - } - if(!(*store)) { /* implicit ctor on first sample */ + if (!(*store)) { /* implicit ctor on first sample */ *store = calloc(1, sizeof(vmon_proc_follow_threads_t)); (*store)->task_dir = opendirf(vmon, vmon->proc_dir, "%i/task", proc->pid); - } else if((*store)->task_dir) { + } else if ((*store)->task_dir) { seekdir((*store)->task_dir, 0); } - if(!(*store)->task_dir) { + if (!(*store)->task_dir) return SAMPLE_ERROR; - } /* unmonitor stale threads on entry, this concludes the two-phase removal of a thread (just like follow_children) */ list_for_each_entry_safe(tmp, _tmp, &proc->threads, threads) { - if(tmp->is_stale) { + if (tmp->is_stale) { vmon_proc_unmonitor(vmon, tmp, NULL, NULL); } #ifdef _MOVE_STALE_TO_FRONT @@ -537,23 +525,20 @@ static int proc_follow_threads(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follow } start = &proc->threads; - while((dentry = readdir((*store)->task_dir))) { + while ((dentry = readdir((*store)->task_dir))) { int tid; - if(dentry->d_name[0] == '.' && (dentry->d_name[1] == '\0' || (dentry->d_name[1] == '.' && dentry->d_name[2] == '\0'))) { - /* skip . and .. */ - continue; - } + if (dentry->d_name[0] == '.' && (dentry->d_name[1] == '\0' || (dentry->d_name[1] == '.' && dentry->d_name[2] == '\0'))) + continue; /* skip . and .. */ tid = atoi(dentry->d_name); found = 0; list_for_each(cur, start) { - if(cur == &proc->threads) { /* take care to skip the head node */ + if (cur == &proc->threads) /* take care to skip the head node */ continue; - } - if(list_entry(cur, vmon_proc_t, threads)->pid == tid) { + if (list_entry(cur, vmon_proc_t, threads)->pid == tid) { /* found the thread already monitored, update its generation number and stop searching */ tmp = list_entry(cur, vmon_proc_t, threads); tmp->generation = vmon->generation; @@ -563,7 +548,7 @@ static int proc_follow_threads(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follow } } - if(found || (tmp = vmon_proc_monitor(vmon, proc, tid, (proc->wants | VMON_INTERNAL_PROC_IS_THREAD), NULL, NULL))) { + if (found || (tmp = vmon_proc_monitor(vmon, proc, tid, (proc->wants | VMON_INTERNAL_PROC_IS_THREAD), NULL, NULL))) { /* position the thread in the threads list, and update the start */ #ifdef _MOVE_STALE_TO_FRONT list_move_tail(&tmp->threads, start); @@ -573,7 +558,7 @@ static int proc_follow_threads(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_follow } list_for_each_entry_safe(tmp, _tmp, &proc->threads, threads) { - if(tmp->generation != vmon->generation) { + if (tmp->generation != vmon->generation) { /* set children not found to stale status so the caller can respond and on our next sample invocation we will unmonitor them */ tmp->is_stale = 1; } @@ -599,26 +584,23 @@ static vmon_fobject_t * fobject_lookup_hinted(vmon_t *vmon, const char *path, vm * the prefixes with the kind of contextual information details we monitor for each of those types. Then when new * fobject types are added to libvmon, the rest of the code automatically reflects the additions due to the mechanization. */ - if(!path || strncmp(path, "pipe:", 5)) { + if (!path || strncmp(path, "pipe:", 5)) return NULL; /* XXX TODO: for now we're only dealing with pipes */ - } sscanf(&path[6], "%" SCNu64 "]", &inum); - if(hint && hint->inum == inum) { - /* the hint matches, skip the search */ - return hint; - } + if (hint && hint->inum == inum) + return hint; /* the hint matches, skip the search */ /* search for the inode, if we can't find it, allocate a new fobject XXX this needs optimizing but silly until we have all object types handled... */ list_for_each_entry(tmp, &vmon->fobjects, bucket) { - if(tmp->inum == inum) { + if (tmp->inum == inum) { fobject = tmp; break; } } - if(!fobject) { + if (!fobject) { /* create a new fobject */ fobject = malloc(sizeof(vmon_fobject_t)); @@ -631,9 +613,8 @@ static vmon_fobject_t * fobject_lookup_hinted(vmon_t *vmon, const char *path, vm list_add_tail(&fobject->bucket, &vmon->fobjects); vmon->fobjects_nr++; - if(vmon->fobject_ctor_cb) { + if (vmon->fobject_ctor_cb) vmon->fobject_ctor_cb(vmon, fobject); - } } return fobject; @@ -645,29 +626,26 @@ static void fobject_ref(vmon_t *vmon, vmon_fobject_t *fobject, vmon_proc_fd_t *f { fobject->refcnt++; - if(fd_ref) { + if (fd_ref) list_add_tail(&fd_ref->ref_fds, &fobject->ref_fds); - } } /* fobject is required and is the object being unrefereced, fd_ref is optional but represents the per-process fd reference being used to access this fobject via */ static int fobject_unref(vmon_t *vmon, vmon_fobject_t *fobject, vmon_proc_fd_t *fd_ref) { - if(fd_ref) { + if (fd_ref) list_del(&fd_ref->ref_fds); - } fobject->refcnt--; - if(!fobject->refcnt) { + if (!fobject->refcnt) { /* after the refcnt drops to zero we discard the fobject */ list_del(&fobject->bucket); vmon->fobjects_nr--; - if(vmon->fobject_dtor_cb) { + if (vmon->fobject_dtor_cb) vmon->fobject_dtor_cb(vmon, fobject); - } free(fobject); return 1; @@ -681,9 +659,8 @@ static int fobject_unref(vmon_t *vmon, vmon_fobject_t *fobject, vmon_proc_fd_t * static void del_fd(vmon_t *vmon, vmon_proc_fd_t *fd) { list_del(&fd->fds); - if(fd->object) { + if (fd->object) fobject_unref(vmon, fd->object, fd); /* note we supply both the fobject ptr and proc_fd ptr (fd) */ - } try_free((void **)&fd->object_path); free(fd); } @@ -692,83 +669,77 @@ static void del_fd(vmon_t *vmon, vmon_proc_fd_t *fd) /* implements the open file descriptors (/proc/$pid/fd/...) sampling */ static sample_ret_t proc_sample_files(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_files_t **store) { - int changes = 0; - struct dirent *dentry; - int fdnum; - list_head_t *cur, *start; - vmon_proc_fd_t *fd, *_fd; - vmon_fobject_t *cur_object = NULL; + int changes = 0; + struct dirent *dentry; + int fdnum; + list_head_t *cur, *start; + vmon_proc_fd_t *fd, *_fd; + vmon_fobject_t *cur_object = NULL; - if(!proc) { + if (!proc) { /* dtor implementation */ - if(--((*store)->refcnt)) { /* suppress dtor while references exist, the store is shared */ + if (--((*store)->refcnt)) /* suppress dtor while references exist, the store is shared */ return DTOR_NOFREE; - } try_closedir(&(*store)->fd_dir); - list_for_each_entry_safe(fd, _fd, &(*store)->fds, fds) { + list_for_each_entry_safe(fd, _fd, &(*store)->fds, fds) del_fd(vmon, fd); - } return DTOR_FREE; } - if(proc->is_thread) { + if (proc->is_thread) { /* don't monitor the open files of threads, instead, share the files store of the parent process by adding a reference to it */ /* XXX TODO: use kcmp CMP_FILES in the future instead of assuming all threads share open files */ - if(!(*store) && ((*store) = proc->parent->stores[VMON_STORE_PROC_FILES])) { + if (!(*store) && ((*store) = proc->parent->stores[VMON_STORE_PROC_FILES])) (*store)->refcnt++; - } + return SAMPLE_UNCHANGED; /* XXX TODO: we actually want to reflect/copy the activity state of the parent */ } - if(!(*store)) { /* implicit ctor on first sample */ + if (!(*store)) { /* implicit ctor on first sample */ *store = calloc(1, sizeof(vmon_proc_files_t)); (*store)->refcnt = 1; (*store)->fd_dir = opendirf(vmon, vmon->proc_dir, "%i/fd", proc->pid); INIT_LIST_HEAD(&(*store)->fds); - } else if((*store)->fd_dir) { + } else if ((*store)->fd_dir) { /* we have a directory handle, and we're reentering the function with the directory positioned at the end */ seekdir((*store)->fd_dir, 0); } - if(!(*store)->fd_dir) { + if (!(*store)->fd_dir) /* we have no directory handle on reentry */ /* XXX TODO: this happens when we don't have permission, this hsould be handled more elegantly/cleanly, and we don't * make any attempt to ever reopen the directory because the ctor has already run. */ goto _fail; - } start = &(*store)->fds; - while((dentry = readdir((*store)->fd_dir))) { - if(dentry->d_name[0] == '.' && (dentry->d_name[1] == '\0' || (dentry->d_name[1] == '.' && dentry->d_name[2] == '\0'))) { - /* skip . and .. */ - continue; - } + while ((dentry = readdir((*store)->fd_dir))) { + if (dentry->d_name[0] == '.' && (dentry->d_name[1] == '\0' || (dentry->d_name[1] == '.' && dentry->d_name[2] == '\0'))) + continue; /* skip . and .. */ fdnum = atoi(dentry->d_name); /* search the process' files list for this fdnum */ fd = NULL; list_for_each(cur, start) { - if(cur == &(*store)->fds) { + if (cur == &(*store)->fds) continue; /* skip the head node as it's not boxed */ - } - if(list_entry(cur, vmon_proc_fd_t, fds)->fdnum == fdnum) { + + if (list_entry(cur, vmon_proc_fd_t, fds)->fdnum == fdnum) { fd = list_entry(cur, vmon_proc_fd_t, fds); break; } } - if(!fd) { + if (!fd) { fd = calloc(1, sizeof(vmon_proc_fd_t)); - if(!fd) { - /* TODO: errors */ - goto _fail; - } + if (!fd) + goto _fail; /* TODO: errors */ + fd->fdnum = fdnum; fd->process = proc; INIT_LIST_HEAD(&fd->ref_fds); @@ -786,14 +757,12 @@ static sample_ret_t proc_sample_files(vmon_t *vmon, vmon_proc_t *proc, vmon_proc cur_object = fd->object; /* stow the current object reference before we potentially replace it so we may unreference it if needed */ fd->object = fobject_lookup_hinted(vmon, fd->object_path.array, cur_object); - if(cur_object != fd->object) { - if(cur_object) { + if (cur_object != fd->object) { + if (cur_object) fobject_unref(vmon, cur_object, fd); - } - if(fd->object) { + if (fd->object) fobject_ref(vmon, fd->object, fd); - } } /* else { lookup returned the same object as before (or NULL), is there anything to do? } */ start = &fd->fds; /* update the search start to this fd */ @@ -801,11 +770,10 @@ static sample_ret_t proc_sample_files(vmon_t *vmon, vmon_proc_t *proc, vmon_proc /* search for stale (closed) fds, remove references for any we find */ list_for_each_entry_safe(fd, _fd, &(*store)->fds, fds) { - if(fd->generation != vmon->generation) { - del_fd(vmon, fd); - } else { + if (fd->generation == vmon->generation) break; - } + + del_fd(vmon, fd); } return changes ? SAMPLE_CHANGED : SAMPLE_UNCHANGED; @@ -829,15 +797,15 @@ static sample_ret_t proc_sample_vm(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_vm #define VMON_PREPARE_PARSER #include "defs/proc_vm.def" - if(!proc) { /* dtor */ + if (!proc) { /* dtor */ try_close(&(*store)->statm_fd); return DTOR_FREE; } - if(!(*store)) { /* ctor */ + if (!(*store)) { /* ctor */ (*store) = calloc(1, sizeof(vmon_proc_vm_t)); - if(proc->is_thread) { + if (proc->is_thread) { (*store)->statm_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/task/%i/statm", proc->pid, proc->pid); } else { (*store)->statm_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/statm", proc->pid); @@ -853,16 +821,16 @@ static sample_ret_t proc_sample_vm(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_vm } /* read in statm and parse it assigning the vm members accordingly */ - while((len = try_read((*store)->statm_fd, vmon->buf, sizeof(vmon->buf))) > 0) { - for(i = 0; i < len; i++) { + while ((len = try_read((*store)->statm_fd, vmon->buf, sizeof(vmon->buf))) > 0) { + for (i = 0; i < len; i++) { /* parse the fields from the file, stepping through... */ input = vmon->buf[i]; - switch(state) { + switch (state) { #define VMON_IMPLEMENT_PARSER #include "defs/proc_vm.def" - default: - /* we're finished parsing once we've fallen off the end of the symbols */ - break; + default: + /* we're finished parsing once we've fallen off the end of the symbols */ + break; } } } @@ -885,15 +853,15 @@ static sample_ret_t proc_sample_io(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_io #define VMON_PREPARE_PARSER #include "defs/proc_io.def" - if(!proc) { /* dtor */ + if (!proc) { /* dtor */ try_close(&(*store)->io_fd); return DTOR_FREE; } - if(!(*store)) { /* ctor */ + if (!(*store)) { /* ctor */ (*store) = calloc(1, sizeof(vmon_proc_io_t)); - if(proc->is_thread) { + if (proc->is_thread) { (*store)->io_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/task/%i/io", proc->pid, proc->pid); } else { (*store)->io_fd = openf(vmon, O_RDONLY, vmon->proc_dir, "%i/io", proc->pid); @@ -909,16 +877,16 @@ static sample_ret_t proc_sample_io(vmon_t *vmon, vmon_proc_t *proc, vmon_proc_io } /* read in io and parse it assigning the io members accordingly */ - while((len = try_read((*store)->io_fd, vmon->buf, sizeof(vmon->buf))) > 0) { - for(i = 0; i < len; i++) { + while ((len = try_read((*store)->io_fd, vmon->buf, sizeof(vmon->buf))) > 0) { + for (i = 0; i < len; i++) { /* parse the fields from the file, stepping through... */ input = vmon->buf[i]; - switch(state) { + switch (state) { #define VMON_IMPLEMENT_PARSER #include "defs/proc_io.def" - default: - /* we're finished parsing once we've fallen off the end of the symbols */ - break; + default: + /* we're finished parsing once we've fallen off the end of the symbols */ + break; } } } @@ -943,28 +911,28 @@ static sample_ret_t sys_sample_stat(vmon_t *vmon, vmon_sys_stat_t **store) #define VMON_PREPARE_PARSER #include "defs/sys_stat.def" - if(!vmon) { /* dtor */ + if (!vmon) { /* dtor */ try_close(&(*store)->stat_fd); return DTOR_FREE; } - if(!(*store)) { /* ctor */ + if (!(*store)) { /* ctor */ (*store) = calloc(1, sizeof(vmon_sys_stat_t)); (*store)->stat_fd = openat(dirfd(vmon->proc_dir), "stat", O_RDONLY); } else { try_lseek((*store)->stat_fd, 0, SEEK_SET); } - while((len = try_read((*store)->stat_fd, vmon->buf, sizeof(vmon->buf))) > 0) { - for(i = 0; i < len; i++) { + while ((len = try_read((*store)->stat_fd, vmon->buf, sizeof(vmon->buf))) > 0) { + for (i = 0; i < len; i++) { input = vmon->buf[i]; - switch(state) { + switch (state) { #define VMON_PARSER_DELIM ' ' /* TODO XXX eliminate the need for this, I want the .def's to include all the data format knowledge */ #define VMON_IMPLEMENT_PARSER #include "defs/sys_stat.def" - default: - /* we're finished parsing once we've fallen off the end of the symbols */ - break; + default: + /* we're finished parsing once we've fallen off the end of the symbols */ + break; } } } @@ -987,12 +955,12 @@ static sample_ret_t sys_sample_vm(vmon_t *vmon, vmon_sys_vm_t **store) #define VMON_PREPARE_PARSER #include "defs/sys_vm.def" - if(!vmon) { /* dtor */ + if (!vmon) { /* dtor */ try_close(&(*store)->meminfo_fd); return DTOR_FREE; } - if(!(*store)) { /* ctor */ + if (!(*store)) { /* ctor */ (*store) = calloc(1, sizeof(vmon_sys_vm_t)); (*store)->meminfo_fd = openat(dirfd(vmon->proc_dir), "meminfo", O_RDONLY); @@ -1003,16 +971,16 @@ static sample_ret_t sys_sample_vm(vmon_t *vmon, vmon_sys_vm_t **store) memset((*store)->changed, 0, sizeof((*store)->changed)); } - while((len = try_read((*store)->meminfo_fd, vmon->buf, sizeof(vmon->buf))) > 0) { - for(i = 0; i < len; i++) { + while ((len = try_read((*store)->meminfo_fd, vmon->buf, sizeof(vmon->buf))) > 0) { + for (i = 0; i < len; i++) { input = vmon->buf[i]; - switch(state) { + switch (state) { #define VMON_PARSER_DELIM ' ' /* TODO XXX eliminate the need for this, I want the .def's to include all the data format knowledge */ #define VMON_IMPLEMENT_PARSER #include "defs/sys_vm.def" - default: - /* we're finished parsing once we've fallen off the end of the symbols */ - break; + default: + /* we're finished parsing once we've fallen off the end of the symbols */ + break; } } } @@ -1028,20 +996,17 @@ int vmon_init(vmon_t *vmon, vmon_flags_t flags, vmon_sys_wants_t sys_wants, vmon { int i; - if((flags & VMON_FLAG_PROC_ALL) && (proc_wants & VMON_WANT_PROC_FOLLOW_CHILDREN)) { + if ((flags & VMON_FLAG_PROC_ALL) && (proc_wants & VMON_WANT_PROC_FOLLOW_CHILDREN)) return 0; - } - if(!(vmon->proc_dir = opendir("/proc"))) { + if (!(vmon->proc_dir = opendir("/proc"))) return 0; - } INIT_LIST_HEAD(&vmon->processes); INIT_LIST_HEAD(&vmon->orphans); - for(i = 0; i < VMON_HTAB_SIZE; i++) { + for (i = 0; i < VMON_HTAB_SIZE; i++) INIT_LIST_HEAD(&vmon->htab[i]); - } memset(vmon->stores, 0, sizeof(vmon->stores)); @@ -1089,27 +1054,27 @@ static int find_proc_in_array(vmon_t *vmon, vmon_proc_t *proc, int hint) { int ret = -1; - if(hint >= 0 && hint < vmon->array_allocated_nr && vmon->array[hint] == proc) { + if (hint >= 0 && hint < vmon->array_allocated_nr && vmon->array[hint] == proc) { /* the hint was accurate, bypass the search */ ret = hint; } else { int i; /* search for the entry in the array */ - for(i = 0; i < vmon->array_allocated_nr; i++) { - if(vmon->array[i] == proc) { + for (i = 0; i < vmon->array_allocated_nr; i++) { + if (vmon->array[i] == proc) { ret = i; break; } } } - if(!proc && ret == -1) { + if (!proc && ret == -1) { vmon_proc_t **tmp; /* enlarge the array */ tmp = realloc(vmon->array, (vmon->array_allocated_nr + VMON_ARRAY_GROWBY) * sizeof(vmon_proc_t *)); - if(tmp) { + if (tmp) { memset(&tmp[vmon->array_allocated_nr], 0, VMON_ARRAY_GROWBY * sizeof(vmon_proc_t *)); ret = vmon->array_hint_free = vmon->array_allocated_nr; vmon->array_allocated_nr += VMON_ARRAY_GROWBY; @@ -1125,20 +1090,19 @@ static int find_proc_in_array(vmon_t *vmon, vmon_proc_t *proc, int hint) /* will not install the same callback function & arg combination more than once, and will not install NULL-functioned callbacks at all! */ static int maybe_install_proc_callback(vmon_t *vmon, list_head_t *callbacks, void (*func)(vmon_t *, void *, vmon_proc_t *, void *), void *arg) { - if(func) { + if (func) { vmon_proc_callback_t *cb; list_for_each_entry(cb, callbacks, callbacks) { - if(cb->func == func && cb->arg == arg) { + if (cb->func == func && cb->arg == arg) break; - } } - if(&cb->callbacks == callbacks) { + if (&cb->callbacks == callbacks) { cb = malloc(sizeof(vmon_proc_callback_t)); - if(!cb) { + if (!cb) return 0; - } + cb->func = func; cb->arg = arg; list_add_tail(&cb->callbacks, callbacks); @@ -1160,14 +1124,14 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon wants &= ~VMON_INTERNAL_PROC_IS_THREAD; - if(pid < 0) return NULL; + if (pid < 0) + return NULL; list_for_each_entry(proc, &vmon->htab[hash], bucket) { /* search for the process to see if it's already monitored, we allow threads to exist with the same pid hence the additional is_thread comparison */ - if(proc->pid == pid && proc->is_thread == is_thread) { - if(!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_arg)) { + if (proc->pid == pid && proc->is_thread == is_thread) { + if (!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_arg)) return NULL; - } proc->wants = wants; /* we can alter wants this way, though it clearly needs more consideration XXX */ proc->refcnt++; @@ -1180,7 +1144,7 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon * What I'm doing for now is allowing the assignment of a parent when there is no parent, but we don't perform the vmon->processes to parent->children migration * until the top-level sample_siblings() function sees the node with the parent. At that point, the node will migrate to the parent's children list. */ - if(parent && !proc->parent) { + if (parent && !proc->parent) { /* if a parent was supplied, and there is no current parent, the process is a top-level currently by external callers, but now appears to be a child of something as well, * so in this scenario, we'll remove it from the top-level siblings list, and make it a child of the new parent. I don't think there needs to be concern about its being a thread here. */ /* Note we can't simply move the process from its current processes list and add it to the supplied parent's children list, as that would break the iterator above us at the top-level, so @@ -1189,17 +1153,15 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon * tree position for users like vwm. */ /* the VMON_FLAG_2PASS flag has been introduced for users like vwm */ proc->parent = parent; - } /* else if(parent && proc->parent) { XXX TODO: it shouldn't be possible to have conflicting parents, but may want to log an error if it happens. */ + } /* else if (parent && proc->parent) { XXX TODO: it shouldn't be possible to have conflicting parents, but may want to log an error if it happens. */ return proc; } } proc = (vmon_proc_t *)malloc(sizeof(vmon_proc_t)); - if(proc == NULL) { - /* TODO: report an error */ - return NULL; - } + if (proc == NULL) + return NULL; /* TODO: report an error */ proc->pid = pid; proc->wants = wants; @@ -1215,14 +1177,14 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon INIT_LIST_HEAD(&proc->siblings); INIT_LIST_HEAD(&proc->threads); - if(!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_arg)) { + if (!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_arg)) { free(proc); return NULL; } - if(parent) { + if (parent) { /* if a parent is specified, attach this process to the parent's children or threads with its siblings */ - if(is_thread) { + if (is_thread) { list_add_tail(&proc->threads, &parent->threads); parent->threads_changed = 1; } else { @@ -1240,7 +1202,7 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon list_add_tail(&proc->bucket, &vmon->htab[hash]); /* if process table maintenance is enabled acquire a free slot for this process */ - if((vmon->flags & VMON_FLAG_PROC_ARRAY) && (i = find_proc_in_array(vmon, NULL, vmon->array_hint_free)) != -1) { + if ((vmon->flags & VMON_FLAG_PROC_ARRAY) && (i = find_proc_in_array(vmon, NULL, vmon->array_hint_free)) != -1) { vmon->array[i] = proc; /* cache where we get inserted into the array */ @@ -1248,9 +1210,8 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon } /* invoke ctor callback if set, note it's only called when a new vmon_proc_t has been instantiated */ - if(vmon->proc_ctor_cb) { + if (vmon->proc_ctor_cb) vmon->proc_ctor_cb(vmon, proc); - } return proc; } @@ -1262,11 +1223,11 @@ void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon vmon_proc_t *child, *_child; int i; - if(sample_cb) { /* uninstall callback */ + if (sample_cb) { /* uninstall callback */ vmon_proc_callback_t *cb, *_cb; list_for_each_entry_safe(cb, _cb, &proc->sample_callbacks, callbacks) { - if(cb->func == sample_cb && cb->arg == sample_cb_arg) { + if (cb->func == sample_cb && cb->arg == sample_cb_arg) { list_del(&cb->callbacks); free(cb); break; @@ -1274,13 +1235,12 @@ void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon } } - if(--(proc->refcnt)) { /* if the process still has references, don't free it */ + if (--(proc->refcnt)) /* if the process still has references, don't free it */ return; - } /* recursively unmonitor any children processes being monitored */ list_for_each_entry_safe(child, _child, &proc->children, siblings) { - if(child->parent == proc) { + if (child->parent == proc) { child->parent = NULL; /* children we're currently a parent of, we're going bye bye, so make them orphans */ list_add_tail(&child->siblings, &vmon->orphans); /* if the child becomes actually dtor'd in the nxt step it immediately will be discarded from the orphans list ... */ } @@ -1288,30 +1248,27 @@ void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon } /* unmonitor all threads being monitored, suppressed if this process is a thread itself, as threads don't have children */ - if(!proc->is_thread) { - list_for_each_entry_safe(child, _child, &proc->threads, threads) { + if (!proc->is_thread) { + list_for_each_entry_safe(child, _child, &proc->threads, threads) vmon_proc_unmonitor(vmon, child, NULL, NULL); - } } /* if maintaining a process array NULL out the entry */ - if((vmon->flags & VMON_FLAG_PROC_ARRAY) && (i = find_proc_in_array(vmon, proc, proc->array_hint_pos)) != -1) { + if ((vmon->flags & VMON_FLAG_PROC_ARRAY) && (i = find_proc_in_array(vmon, proc, proc->array_hint_pos)) != -1) { vmon->array[i] = NULL; /* store its index if the current free hint isn't free, or it's lower than the current free hint, making the hint useful */ - if(vmon->array[vmon->array_hint_free] || i < vmon->array_hint_free) { + if (vmon->array[vmon->array_hint_free] || i < vmon->array_hint_free) vmon->array_hint_free = i; - } } list_del(&proc->siblings); - if(proc->is_thread) { + if (proc->is_thread) list_del(&proc->threads); - } list_del(&proc->bucket); - if(proc->parent) { /* XXX TODO: verify this works ok for unmonitored orphans */ + if (proc->parent) { /* XXX TODO: verify this works ok for unmonitored orphans */ /* set the children changed flag in the parent */ - if(proc->is_thread) { + if (proc->is_thread) { proc->parent->threads_changed = 1; } else { proc->parent->children_changed = 1; /* XXX TODO: for now I modify children_changed for both when the child dtor occurs and is_stale gets set */ @@ -1321,19 +1278,16 @@ void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon vmon->processes_changed = 1; } - for(i = 0; i < sizeof(vmon->proc_funcs) / sizeof(vmon->proc_funcs[VMON_STORE_PROC_STAT]); i++) { - if(proc->stores[i] != NULL) { /* any non-NULL stores must have a function installed and must have been sampled, invoke the dtor branch */ - if(vmon->proc_funcs[i](vmon, NULL, &proc->stores[i]) == DTOR_FREE) { - free(proc->stores[i]); - } - proc->stores[i] = NULL; + for (i = 0; i < sizeof(vmon->proc_funcs) / sizeof(vmon->proc_funcs[VMON_STORE_PROC_STAT]); i++) { + if (proc->stores[i] != NULL) { /* any non-NULL stores must have a function installed and must have been sampled, invoke the dtor branch */ + if (vmon->proc_funcs[i](vmon, NULL, &proc->stores[i]) == DTOR_FREE) + try_free((void **)&proc->stores[i]); } } /* invoke the dtor if set, note it only happens when the vmon_proc_t instance is about to be freed, not when it transitions to proc.is_stale=1 */ - if(vmon->proc_dtor_cb) { + if (vmon->proc_dtor_cb) vmon->proc_dtor_cb(vmon, proc); - } free(proc); } @@ -1350,11 +1304,11 @@ static void sample(vmon_t *vmon, vmon_proc_t *proc) wants = proc->wants ? proc->wants : vmon->proc_wants; proc->activity = 0; - for(i = 0, cur = 1; wants; cur <<= 1, i++) { - if(wants & cur) { - if(vmon->proc_funcs[i](vmon, proc, &proc->stores[i]) == SAMPLE_CHANGED) { + for (i = 0, cur = 1; wants; cur <<= 1, i++) { + if (wants & cur) { + if (vmon->proc_funcs[i](vmon, proc, &proc->stores[i]) == SAMPLE_CHANGED) proc->activity |= cur; - } + wants &= ~cur; } } @@ -1373,9 +1327,8 @@ static int sample_threads(vmon_t *vmon, list_head_t *threads) /* callbacks can't be installed currently on threads */ vmon_proc_callback_t *cb; - list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { + list_for_each_entry(cb, &proc->sample_callbacks, callbacks) cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); - } #endif } @@ -1393,9 +1346,8 @@ static int sample_siblings(vmon_t *vmon, list_head_t *siblings) int entered_new = 0; /* prepare to transition top-level processes out of the is_new state, there's no sampler acting on behalf of top-level processes */ - if(proc->is_new) { + if (proc->is_new) entered_new = 1; - } sample(vmon, proc); /* invoke samplers for this node */ sample_threads(vmon, &proc->threads); /* invoke samplers for this node's threads */ @@ -1403,7 +1355,7 @@ static int sample_siblings(vmon_t *vmon, list_head_t *siblings) /* XXX TODO: error returns */ /* if this is the top-level processes list, and proc has found a parent through the above sampling, migrate it to the parent's children list */ - if(siblings == &vmon->processes && proc->parent) { + if (siblings == &vmon->processes && proc->parent) { list_del(&proc->siblings); list_add_tail(&proc->siblings, &proc->parent->children); continue; @@ -1413,22 +1365,19 @@ static int sample_siblings(vmon_t *vmon, list_head_t *siblings) * this enables the installation of a callback at a specific node in the process heirarchy which can also perform duties on behalf of the children * being monitored, handy when automatically following children, an immediately relevant use case (vwm) */ - list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { + list_for_each_entry(cb, &proc->sample_callbacks, callbacks) cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); - } /* transition new to non-new processes where we're responsible, this is a slight problem */ - if(!proc->parent && entered_new) { + if (!proc->parent && entered_new) proc->is_new = 0; - } } /* if we've just finished the top-level processes, and we have some orphans, we want to make the orphans top-level processes and sample them as such */ - if(siblings == &vmon->processes && !list_empty(&vmon->orphans)) { + if (siblings == &vmon->processes && !list_empty(&vmon->orphans)) /* XXX TODO: do I need to get these orphans sampled immediately for this sample? Are they getting skipped this sample? * TODO: instrument the samplers to see if generation is > 1 behind to detect drops... */ list_splice_init(&vmon->orphans, vmon->processes.prev); - } return 1; } @@ -1449,23 +1398,22 @@ static int sample_siblings_pass1(vmon_t *vmon, list_head_t *siblings) /* if this is the top-level processes list, and proc has found a parent through the above sampling, migrate it to the parent's children list */ /* XXX: clarification; a process may have been monitored explicitly by an external caller which then becomes monitored as the followed child of * another process, here we detect that and move the process out of the top-level processes list and down to the children list it belongs to. */ - if(siblings == &vmon->processes) { + if (siblings == &vmon->processes) { /* XXX: nobody maintains the generation numbers for the top-level processes, so it's done here... * TODO: detect exited top-level processes and do something useful? */ proc->generation = vmon->generation; - if(proc->parent) { + if (proc->parent) { list_del(&proc->siblings); list_add_tail(&proc->siblings, &proc->parent->children); } } } - if(siblings == &vmon->processes && !list_empty(&vmon->orphans)) { + if (siblings == &vmon->processes && !list_empty(&vmon->orphans)) /* XXX TODO: do I need to get these orphans sampled immediately for this sample? Are they getting skipped this sample? * TODO: instrument the samplers to see if generation is > 1 behind to detect drops and log as bugs... */ list_splice_init(&vmon->orphans, vmon->processes.prev); - } return 1; } @@ -1485,13 +1433,12 @@ static int sample_siblings_pass2(vmon_t *vmon, list_head_t *siblings) cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); } - if(!proc->parent && proc->is_new) { /* top-level processes aren't managed by a follower/sampler, so we need to clear their is_new flag, this approach is slightly deviant from the managed case, + if (!proc->parent && proc->is_new) /* top-level processes aren't managed by a follower/sampler, so we need to clear their is_new flag, this approach is slightly deviant from the managed case, * as the managed case will actually allow the process to retain its is_new flag across a vmon_sample() cycle, where we're clearing it @ exit. It makes * no difference to the callbacks, but if someone walks the tree after vmon_sample() relying on is_new, they'll be confused. XXX TODO FIXME * May be able to leverage the generation number and turn the top-level sampler into more of a follower analog??? */ proc->is_new = 0; - } } return 1; @@ -1507,7 +1454,7 @@ int vmon_sample(vmon_t *vmon) /* first manage the "all processes monitored" use case, this doesn't do any sampling, it just maintains the top-level list of processes being monitored */ /* note this doesn't cover threads, as linux doesn't expose threads in the readdir of /proc, even though you can directly look them up at /proc/$tid */ - if((vmon->flags & VMON_FLAG_PROC_ALL)) { + if ((vmon->flags & VMON_FLAG_PROC_ALL)) { struct dirent *dentry; list_head_t *tmp, *_tmp = &vmon->processes; @@ -1515,36 +1462,31 @@ int vmon_sample(vmon_t *vmon) * as a process to monitor. The list of toplevel processes being monitored is kept in sync with these, automatically monitoring * new processes found, and unmonitoring processes now absent, in a fashion very similar to the proc_sample_files() code. */ seekdir(vmon->proc_dir, 0); - while((dentry = readdir(vmon->proc_dir))) { + while ((dentry = readdir(vmon->proc_dir))) { int pid, found; - if(dentry->d_type != DT_DIR || dentry->d_name[0] < '0' || dentry->d_name[0] > '9') { - /* skip non-directories and non-numeric directories */ - continue; - } + if (dentry->d_type != DT_DIR || dentry->d_name[0] < '0' || dentry->d_name[0] > '9') + continue; /* skip non-directories and non-numeric directories */ pid = atoi(dentry->d_name); found = 0; list_for_each(tmp, _tmp) { /* note how we use _tmp as the head for the processes iteration, resuming from the last process' node */ - if(tmp == &vmon->processes) { + if (tmp == &vmon->processes) continue; /* must take care to skip the processes list_head_t, as it's not a vmon_proc_t */ - } - if(list_entry(tmp, vmon_proc_t, siblings)->pid == pid) { + if (list_entry(tmp, vmon_proc_t, siblings)->pid == pid) { found = 1; break; } } - if(!found) { + if (!found) { /* monitor the process */ vmon_proc_t *proc = vmon_proc_monitor(vmon, NULL, pid, vmon->proc_wants, NULL, NULL); - if(!proc) { - /* TODO error */ - continue; - } + if (!proc) + continue; /* TODO error */ tmp = &proc->siblings; } @@ -1557,7 +1499,7 @@ int vmon_sample(vmon_t *vmon) } list_for_each_safe(tmp, _tmp, &vmon->processes) { /* XXX safe version needed since vmon_proc_unmonitor() deletes from the processes list */ - if(list_entry(tmp, vmon_proc_t, siblings)->generation != vmon->generation) { + if (list_entry(tmp, vmon_proc_t, siblings)->generation != vmon->generation) { vmon_proc_unmonitor(vmon, list_entry(tmp, vmon_proc_t, siblings), NULL, NULL); } else { /* we can stop looking for stale processes upon finding a non-stale one, since they've been sorted by the above algorithm */ @@ -1571,21 +1513,20 @@ int vmon_sample(vmon_t *vmon) /* first the sys-wide samplers */ wants = vmon->sys_wants; /* the caller-requested sys-wide wants */ vmon->activity = 0; - for(i = 0, cur = 1; wants; cur <<= 1, i++) { - if(wants & cur) { - if(vmon->sys_funcs[i](vmon, &vmon->stores[i]) == SAMPLE_CHANGED) { + for (i = 0, cur = 1; wants; cur <<= 1, i++) { + if (wants & cur) { + if (vmon->sys_funcs[i](vmon, &vmon->stores[i]) == SAMPLE_CHANGED) vmon->activity |= cur; - } + wants &= ~cur; } } - if(vmon->sample_cb) { + if (vmon->sample_cb) vmon->sample_cb(vmon, vmon->sample_cb_arg); - } /* then the per-process samplers */ - if((vmon->flags & VMON_FLAG_PROC_ARRAY)) { + if ((vmon->flags & VMON_FLAG_PROC_ARRAY)) { int j; /* TODO: determine if this really makes sense, if we always maintain a heirarchy even in array mode, then we * should probably always sample in the heirarchical order, or maybe make it caller-specified. @@ -1598,26 +1539,24 @@ int vmon_sample(vmon_t *vmon) /* flat process-array ordered sampling, in this mode threads and processes are all placed flatly in the array, * so this does the sampling for all monitored in no particular order */ - for(j = 0; j < vmon->array_allocated_nr; j++) { + for (j = 0; j < vmon->array_allocated_nr; j++) { vmon_proc_t *proc; - if((proc = vmon->array[j])) { + if ((proc = vmon->array[j])) { vmon_proc_callback_t *cb; sample(vmon, proc); - list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { + list_for_each_entry(cb, &proc->sample_callbacks, callbacks) cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); - } /* age process, we use the presence of a parent as a flag indicating if the process is managed ala follow children/threads * XXX TODO: should probably change the public _monitor() api to not contain a parent param then */ - if(!proc->parent && proc->is_new) { + if (!proc->parent && proc->is_new) proc->is_new = 0; - } } } - } else if((vmon->flags & VMON_FLAG_2PASS)) { + } else if ((vmon->flags & VMON_FLAG_2PASS)) { /* recursive heirarchical depth-first processes tree sampling, at each node threads come before children, done in two passes: * Pass 1. samplers * Pass 2. callbacks |