cache args when using ucb/ps

This commit is contained in:
Doug MacEachern 2005-12-10 02:33:49 +00:00
parent 50f8e4e4b6
commit 9414b07011
2 changed files with 78 additions and 25 deletions

View File

@ -225,6 +225,7 @@ struct sigar_t {
proc_exename_func_t pexename; proc_exename_func_t pexename;
sigar_cache_t *fsdev; sigar_cache_t *fsdev;
sigar_cache_t *pargs;
solaris_mib2_t mib2; solaris_mib2_t mib2;
}; };

View File

@ -100,6 +100,7 @@ int sigar_os_open(sigar_t **sig)
sigar->pobjname = NULL; sigar->pobjname = NULL;
sigar->fsdev = NULL; sigar->fsdev = NULL;
sigar->pargs = NULL;
SIGAR_ZERO(&sigar->mib2); SIGAR_ZERO(&sigar->mib2);
sigar->mib2.sd = -1; sigar->mib2.sd = -1;
@ -142,6 +143,9 @@ int sigar_os_close(sigar_t *sigar)
if (sigar->fsdev) { if (sigar->fsdev) {
sigar_cache_destroy(sigar->fsdev); sigar_cache_destroy(sigar->fsdev);
} }
if (sigar->pargs) {
sigar_cache_destroy(sigar->pargs);
}
free(sigar); free(sigar);
return SIGAR_OK; return SIGAR_OK;
} }
@ -676,12 +680,56 @@ static char *sigar_getword(char **line, char stop)
return res; return res;
} }
static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid, typedef struct {
sigar_proc_args_t *procargs) int timestamp;
{ char *args;
char buffer[9086], *args; } pargs_t;
FILE *fp;
static void pargs_free(void *value)
{
pargs_t *pargs = (pargs_t *)value;
if (pargs->args != NULL) {
free(pargs->args);
}
free(pargs);
}
static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
sigar_proc_args_t *procargs,
int timestamp)
{
char buffer[9086], *args, *arg;
sigar_cache_entry_t *ent;
FILE *fp;
pargs_t *pargs;
if (!sigar->pargs) {
sigar->pargs = sigar_cache_new(15);
sigar->pargs->free_value = pargs_free;
}
ent = sigar_cache_get(sigar->pargs, pid);
if (ent->value) {
pargs = (pargs_t *)ent->value;
if (pargs->timestamp != timestamp) {
if (pargs->args) {
free(pargs->args);
pargs->args = NULL;
}
}
}
else {
pargs = malloc(sizeof(*pargs));
pargs->args = NULL;
ent->value = pargs;
}
pargs->timestamp = timestamp;
if (pargs->args) {
args = pargs->args;
}
else {
sprintf(buffer, "/usr/ucb/ps -ww %ld", pid); sprintf(buffer, "/usr/ucb/ps -ww %ld", pid);
if (!(fp = popen(buffer, "r"))) { if (!(fp = popen(buffer, "r"))) {
@ -691,7 +739,6 @@ static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
(void)fgets(buffer, sizeof(buffer), fp); (void)fgets(buffer, sizeof(buffer), fp);
if ((args = fgets(buffer, sizeof(buffer), fp))) { if ((args = fgets(buffer, sizeof(buffer), fp))) {
int len; int len;
char *arg;
/* skip PID,TT,S,TIME */ /* skip PID,TT,S,TIME */
args = sigar_skip_multiple_token(args, 4); args = sigar_skip_multiple_token(args, 4);
@ -699,15 +746,19 @@ static int ucb_ps_args_get(sigar_t *sigar, sigar_pid_t pid,
len = strlen(args); len = strlen(args);
args[len-1] = '\0'; /* chop \n */ args[len-1] = '\0'; /* chop \n */
pargs->args = malloc(len+1);
memcpy(pargs->args, args, len);
}
pclose(fp);
}
sigar_proc_args_create(procargs); sigar_proc_args_create(procargs);
while (*args && (arg = sigar_getword(&args, ' '))) { while (*args && (arg = sigar_getword(&args, ' '))) {
SIGAR_PROC_ARGS_GROW(procargs); SIGAR_PROC_ARGS_GROW(procargs);
procargs->data[procargs->number++] = arg; procargs->data[procargs->number++] = arg;
} }
}
pclose(fp);
return SIGAR_OK; return SIGAR_OK;
} }
@ -748,7 +799,8 @@ int sigar_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
if ((fd = open(buffer, O_RDONLY)) < 0) { if ((fd = open(buffer, O_RDONLY)) < 0) {
if ((errno == EACCES) && sigar->use_ucb_ps) { if ((errno == EACCES) && sigar->use_ucb_ps) {
return ucb_ps_args_get(sigar, pid, procargs); return ucb_ps_args_get(sigar, pid, procargs,
pinfo->pr_start.tv_sec);
} }
else { else {
return PROC_ERRNO; return PROC_ERRNO;