diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -1257,10 +1257,19 @@ size_t intrcntlen; uintptr_t kaddr; - if (kd != NULL) { + if (kd != NULL) kread(X_SINTRCNT, &intrcntlen, sizeof(intrcntlen)); - if ((*intrcnts = malloc(intrcntlen)) == NULL) - err(1, "malloc()"); + else + if (mysysctl("hw.intrcnt", NULL, &intrcntlen) != 0) + err(1, "mysysctl()"); + + if (intrcnts == NULL) + return (intrcntlen / sizeof(unsigned long)); + + if ((*intrcnts = malloc(intrcntlen)) == NULL) + err(1, "malloc()"); + + if (kd != NULL) { if (namelist[X_NINTRCNT].n_type == 0) kread(X_INTRCNT, *intrcnts, intrcntlen); else { @@ -1268,13 +1277,8 @@ kreadptr(kaddr, *intrcnts, intrcntlen); } } else { - for (*intrcnts = NULL, intrcntlen = 1024; ; intrcntlen *= 2) { - *intrcnts = reallocf(*intrcnts, intrcntlen); - if (*intrcnts == NULL) - err(1, "reallocf()"); - if (mysysctl("hw.intrcnt", *intrcnts, &intrcntlen) == 0) - break; - } + if (mysysctl("hw.intrcnt", *intrcnts, &intrcntlen) != 0) + err(1, "mysysctl()"); } return (intrcntlen / sizeof(unsigned long)); @@ -1282,31 +1286,30 @@ static void print_intrcnts(unsigned long *intrcnts, unsigned long *old_intrcnts, - char *intrnames, unsigned int nintr, size_t istrnamlen, long long period_ms) + unsigned short namesz, char *intrnames, unsigned int nintr, + size_t istrnamlen, long long period_ms) { - unsigned long *intrcnt, *old_intrcnt; - char *intrname; uint64_t inttotal, old_inttotal, total_count, total_rate; unsigned long count, rate; unsigned int i; inttotal = 0; old_inttotal = 0; - intrname = intrnames; xo_open_list("interrupt"); - for (i = 0, intrcnt=intrcnts, old_intrcnt=old_intrcnts; i < nintr; i++) { - if (intrname[0] != '\0' && (*intrcnt != 0 || aflag)) { - count = *intrcnt - *old_intrcnt; + for (i = 0; i < nintr; i++) { + if (*intrcnts != 0 || (aflag >= 1 && intrnames[0] != '\0') || + aflag >= 2) { + count = *intrcnts - *old_intrcnts; rate = ((uint64_t)count * 1000 + period_ms / 2) / period_ms; xo_open_instance("interrupt"); xo_emit("{d:name/%-*s}{ket:name/%s} " "{:total/%20lu} {:rate/%10lu}\n", - (int)istrnamlen, intrname, intrname, count, rate); + (int)istrnamlen, intrnames, intrnames, count, rate); xo_close_instance("interrupt"); } - intrname += strlen(intrname) + 1; - inttotal += *intrcnt++; - old_inttotal += *old_intrcnt++; + intrnames += namesz; + inttotal += *intrcnts++; + old_inttotal += *old_intrcnts++; } total_count = inttotal - old_inttotal; total_rate = (total_count * 1000 + period_ms / 2) / period_ms; @@ -1323,6 +1326,7 @@ char *intrname, *intrnames; long long period_ms, old_uptime, uptime; size_t clen, inamlen, istrnamlen; + unsigned short namesz; uintptr_t kaddr; unsigned int nintr; @@ -1341,22 +1345,24 @@ kreadptr(kaddr, intrnames, inamlen); } } else { - for (intrnames = NULL, inamlen = 1024; ; inamlen *= 2) { - if ((intrnames = reallocf(intrnames, inamlen)) == NULL) - xo_err(1, "reallocf()"); - if (mysysctl("hw.intrnames", intrnames, &inamlen) == 0) - break; - } + if (mysysctl("hw.intrnames", NULL, &inamlen) != 0) + xo_err(1, "sysctl()"); + if ((intrnames = malloc(inamlen)) == NULL) + xo_err(1, "malloc()"); + if (mysysctl("hw.intrnames", intrnames, &inamlen) != 0) + xo_err(1, "sysctl()"); } + /* Identify the interrupt name length */ + namesz = inamlen / read_intrcnts(NULL); + /* Determine the length of the longest interrupt name */ - intrname = intrnames; istrnamlen = strlen("interrupt"); - while(*intrname != '\0') { + for(intrname = intrnames; intrname < intrnames + inamlen; + intrname += namesz) { clen = strlen(intrname); if (clen > istrnamlen) istrnamlen = clen; - intrname += strlen(intrname) + 1; } xo_emit("{T:/%-*s} {T:/%20s} {T:/%10s}\n", (int)istrnamlen, "interrupt", "total", "rate"); @@ -1380,7 +1386,7 @@ xo_err(1, "calloc()"); } - print_intrcnts(intrcnts, old_intrcnts, intrnames, nintr, + print_intrcnts(intrcnts, old_intrcnts, namesz, intrnames, nintr, istrnamlen, period_ms); xo_flush();