From 6bafd4b4cc53ae47185714d7c8a19e00d73f6362 Mon Sep 17 00:00:00 2001 From: martijn Date: Sun, 11 Feb 2018 09:47:33 +0000 Subject: [PATCH] Make sorting in the pcache view work. This allows us to sort on all shown columns. There's still parts that could do with a good polishing, but it's an improvement. OK tedu@ --- usr.bin/systat/pool.c | 229 +++++++++++++++++++++++++++++++++++++--- usr.bin/systat/systat.1 | 10 +- 2 files changed, 216 insertions(+), 23 deletions(-) diff --git a/usr.bin/systat/pool.c b/usr.bin/systat/pool.c index bbe49af107e..d56e66dd957 100644 --- a/usr.bin/systat/pool.c +++ b/usr.bin/systat/pool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pool.c,v 1.16 2018/02/08 13:22:25 martijn Exp $ */ +/* $OpenBSD: pool.c,v 1.17 2018/02/11 09:47:33 martijn Exp $ */ /* * Copyright (c) 2008 Can Erkin Acar * @@ -74,6 +74,7 @@ int num_pools = 0; struct pool_info *pools = NULL; int num_pool_caches = 0; struct pool_cache_info *pool_caches = NULL; +size_t pool_caches_size = 0; int ncpusfound = 0; @@ -137,6 +138,14 @@ void pool_cache_print(void); int pool_cache_read(void); void pool_cache_sort(void); void pool_cache_show(const struct pool_cache_info *); +int pool_cache_sort_name_callback(const void *, const void *); +int pool_cache_sort_len_callback(const void *, const void *); +int pool_cache_sort_idle_callback(const void *, const void *); +int pool_cache_sort_ngc_callback(const void *, const void *); +int pool_cache_sort_req_callback(const void *, const void *); +int pool_cache_sort_put_callback(const void *, const void *); +int pool_cache_sort_lreq_callback(const void *, const void *); +int pool_cache_sort_lput_callback(const void *, const void *); int pool_cache_kbd_cb(int); field_def pool_cache_fields[] = { @@ -175,16 +184,21 @@ field_def *view_pool_cache_0[] = { }; order_type pool_cache_order_list[] = { - {"name", "name", 'N', sort_name_callback}, - {"requests", "requests", 'G', sort_req_callback}, - {"releases", "releases", 'P', sort_req_callback}, + {"name", "name", 'N', pool_cache_sort_name_callback}, + {"len", "len", 'L', pool_cache_sort_len_callback}, + {"idle", "idle", 'I', pool_cache_sort_idle_callback}, + {"ngc", "ngc", 'G', pool_cache_sort_ngc_callback}, + {"requests", "requests", 'Q', pool_cache_sort_req_callback}, + {"releases", "releases", 'P', pool_cache_sort_put_callback}, + {"listrequests", "listrequests", 'E', pool_cache_sort_req_callback}, + {"listreleases", "listreleases", 'U', pool_cache_sort_put_callback}, {NULL, NULL, 0, NULL} }; /* Define view managers */ struct view_manager pool_cache_mgr = { "PoolCache", - select_pool, + NULL, pool_cache_read, pool_cache_sort, print_header, @@ -444,7 +458,7 @@ pool_cache_read(void) return (-1); } - if (np > num_pool_caches) { + if (np > pool_caches_size) { pc = reallocarray(pool_caches, np, sizeof(*pc)); if (pc == NULL) { error("realloc: %s", strerror(errno)); @@ -453,7 +467,7 @@ pool_cache_read(void) /* commit to using the new memory */ pool_caches = pc; - for (i = num_pool_caches; i < np; i++) { + for (i = pool_caches_size; i < np; i++) { pc = &pool_caches[i]; pc->name[0] = '\0'; @@ -466,11 +480,12 @@ pool_cache_read(void) } /* commit to using the new cache_infos */ - num_pool_caches = np; + pool_caches_size = np; } - for (i = 0; i < num_pool_caches; i++) { - pc = &pool_caches[i]; + num_pool_caches = 0; + for (i = 0; i < pool_caches_size; i++) { + pc = &pool_caches[num_pool_caches]; np = i + 1; if (pool_get_cache(np, &pc->cache) < 0 || @@ -481,12 +496,13 @@ pool_cache_read(void) if (pool_get_name(np, pc->name, sizeof(pc->name)) < 0) snprintf(pc->name, sizeof(pc->name), "#%d#", i + 1); + num_pool_caches++; } return 0; unalloc: - while (i > num_pool_caches) { + while (i > pool_caches_size) { pc = &pool_caches[--i]; free(pc->cache_cpus); } @@ -496,7 +512,6 @@ unalloc: void pool_cache_sort(void) { - /* XXX */ order_type *ordering; if (curr_mgr == NULL) @@ -508,12 +523,12 @@ pool_cache_sort(void) return; if (ordering->func == NULL) return; - if (pools == NULL) + if (pool_caches == NULL) return; - if (num_pools <= 0) + if (num_pool_caches <= 0) return; - mergesort(pools, num_pools, sizeof(struct pool_info), ordering->func); + mergesort(pool_caches, num_pool_caches, sizeof(*pool_caches), ordering->func); } void @@ -565,10 +580,192 @@ pool_cache_show(const struct pool_cache_info *pc) print_fld_size(FLD_POOL_CACHE_LPUT, kpcc->pr_nlput); end_line(); } +} + +int +pool_cache_sort_name_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + return strcmp(pc1->name, pc2->name) * sortdir; } -static int +int +pool_cache_sort_len_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + if (pc1->cache.pr_len < pc2->cache.pr_len) + return sortdir; + if (pc1->cache.pr_len > pc2->cache.pr_len) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int +pool_cache_sort_idle_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + if (pc1->cache.pr_nitems < pc2->cache.pr_nitems) + return sortdir; + if (pc1->cache.pr_nitems > pc2->cache.pr_nitems) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int +pool_cache_sort_ngc_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + if (pc1->cache.pr_ngc < pc2->cache.pr_ngc) + return sortdir; + if (pc1->cache.pr_ngc > pc2->cache.pr_ngc) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int +pool_cache_sort_req_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + uint64_t nget1 = 0, nget2 = 0; + int oflow1 = 0, oflow2 = 0; + int cpu; + + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + for (cpu = 0; cpu < ncpusfound; cpu++) { + if (nget1 + pc1->cache_cpus->pr_nget < nget1) + oflow1++; + nget1 += pc1->cache_cpus->pr_nget; + if (nget2 + pc2->cache_cpus->pr_nget < nget2) + oflow2++; + nget2 += pc2->cache_cpus->pr_nget; + } + + if (oflow1 < oflow2) + return sortdir; + if (oflow1 > oflow2) + return -sortdir; + if (nget1 < nget2) + return sortdir; + if (nget1 > nget2) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int +pool_cache_sort_put_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + uint64_t nput1 = 0, nput2 = 0; + int oflow1 = 0, oflow2 = 0; + int cpu; + + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + for (cpu = 0; cpu < ncpusfound; cpu++) { + if (nput1 + pc1->cache_cpus->pr_nput < nput1) + oflow1++; + nput1 += pc1->cache_cpus->pr_nput; + if (nput2 + pc2->cache_cpus->pr_nput < nput2) + oflow2++; + nput2 += pc2->cache_cpus->pr_nput; + } + + if (oflow1 < oflow2) + return sortdir; + if (oflow1 > oflow2) + return -sortdir; + if (nput1 < nput2) + return sortdir; + if (nput1 > nput2) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int +pool_cache_sort_lreq_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + uint64_t nlget1 = 0, nlget2 = 0; + int oflow1 = 0, oflow2 = 0; + int cpu; + + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + for (cpu = 0; cpu < ncpusfound; cpu++) { + if (nlget1 + pc1->cache_cpus->pr_nlget < nlget1) + oflow1++; + nlget1 += pc1->cache_cpus->pr_nlget; + if (nlget2 + pc2->cache_cpus->pr_nlget < nlget2) + oflow2++; + nlget2 += pc2->cache_cpus->pr_nlget; + } + + if (oflow1 < oflow2) + return sortdir; + if (oflow1 > oflow2) + return -sortdir; + if (nlget1 < nlget2) + return sortdir; + if (nlget1 > nlget2) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int +pool_cache_sort_lput_callback(const void *s1, const void *s2) +{ + struct pool_cache_info *pc1, *pc2; + uint64_t nlput1 = 0, nlput2 = 0; + int oflow1 = 0, oflow2 = 0; + int cpu; + + pc1 = (struct pool_cache_info *)s1; + pc2 = (struct pool_cache_info *)s2; + + for (cpu = 0; cpu < ncpusfound; cpu++) { + if (nlput1 + pc1->cache_cpus->pr_nlput < nlput1) + oflow1++; + nlput1 += pc1->cache_cpus->pr_nlput; + if (nlput2 + pc2->cache_cpus->pr_nlput < nlput2) + oflow2++; + nlput2 += pc2->cache_cpus->pr_nlput; + } + + if (oflow1 < oflow2) + return sortdir; + if (oflow1 > oflow2) + return -sortdir; + if (nlput1 < nlput2) + return sortdir; + if (nlput1 > nlput2) + return -sortdir; + + return pool_cache_sort_name_callback(s1, s2); +} + +int pool_get_npools(void) { int mib[] = { CTL_KERN, KERN_POOL, KERN_POOL_NPOOLS }; diff --git a/usr.bin/systat/systat.1 b/usr.bin/systat/systat.1 index f3a33ee9b26..4c9376570ba 100644 --- a/usr.bin/systat/systat.1 +++ b/usr.bin/systat/systat.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: systat.1,v 1.103 2018/02/08 07:00:33 martijn Exp $ +.\" $OpenBSD: systat.1,v 1.104 2018/02/11 09:47:33 martijn Exp $ .\" $NetBSD: systat.1,v 1.6 1996/05/10 23:16:39 thorpej Exp $ .\" .\" Copyright (c) 1985, 1990, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)systat.1 8.2 (Berkeley) 12/30/93 .\" -.Dd $Mdocdate: February 8 2018 $ +.Dd $Mdocdate: February 11 2018 $ .Dt SYSTAT 1 .Os .Sh NAME @@ -386,11 +386,7 @@ changes the view to show all of them. Display kernel .Xr pool 9 per CPU cache statistics. -Available orderings are: -.Ic name , -.Ic request , -and -.Ic releases . +Ordering is available on all columns. .It Ic queues Display statistics about the active queues, similar to the output of -- 2.20.1