1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <libintl.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <strings.h>
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate #include "prstat.h"
35*0Sstevel@tonic-gate #include "prutil.h"
36*0Sstevel@tonic-gate #include "prsort.h"
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gate void
list_alloc(list_t * list,int size)39*0Sstevel@tonic-gate list_alloc(list_t *list, int size)
40*0Sstevel@tonic-gate {
41*0Sstevel@tonic-gate if (size > 0) {
42*0Sstevel@tonic-gate list->l_size = size;
43*0Sstevel@tonic-gate list->l_ptrs = Zalloc(sizeof (void *) * (size + 1));
44*0Sstevel@tonic-gate }
45*0Sstevel@tonic-gate }
46*0Sstevel@tonic-gate
47*0Sstevel@tonic-gate void
list_free(list_t * list)48*0Sstevel@tonic-gate list_free(list_t *list)
49*0Sstevel@tonic-gate {
50*0Sstevel@tonic-gate if (list && list->l_ptrs) {
51*0Sstevel@tonic-gate free(list->l_ptrs);
52*0Sstevel@tonic-gate list->l_ptrs = NULL;
53*0Sstevel@tonic-gate }
54*0Sstevel@tonic-gate }
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate /*
57*0Sstevel@tonic-gate * Sorting routines
58*0Sstevel@tonic-gate */
59*0Sstevel@tonic-gate static ulong_t
get_cpu_from_psinfo(void * lwp)60*0Sstevel@tonic-gate get_cpu_from_psinfo(void *lwp)
61*0Sstevel@tonic-gate {
62*0Sstevel@tonic-gate return ((ulong_t)
63*0Sstevel@tonic-gate FRC2PCT((((lwp_info_t *)lwp)->li_info.pr_lwp.pr_pctcpu)*1000));
64*0Sstevel@tonic-gate }
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate static ulong_t
get_cpu_from_usage(void * lwp)67*0Sstevel@tonic-gate get_cpu_from_usage(void *lwp)
68*0Sstevel@tonic-gate {
69*0Sstevel@tonic-gate lwp_info_t *p = (lwp_info_t *)lwp;
70*0Sstevel@tonic-gate float cpu = 0;
71*0Sstevel@tonic-gate cpu += p->li_usr;
72*0Sstevel@tonic-gate cpu += p->li_sys;
73*0Sstevel@tonic-gate cpu *= 1000;
74*0Sstevel@tonic-gate return ((ulong_t)cpu);
75*0Sstevel@tonic-gate }
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate static ulong_t
get_time(void * lwp)78*0Sstevel@tonic-gate get_time(void *lwp)
79*0Sstevel@tonic-gate {
80*0Sstevel@tonic-gate return ((ulong_t)TIME2SEC(((lwp_info_t *)lwp)->li_info.pr_lwp.pr_time));
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate static ulong_t
get_size(void * lwp)84*0Sstevel@tonic-gate get_size(void *lwp)
85*0Sstevel@tonic-gate {
86*0Sstevel@tonic-gate return ((ulong_t)((lwp_info_t *)lwp)->li_info.pr_size);
87*0Sstevel@tonic-gate }
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate static ulong_t
get_rssize(void * lwp)90*0Sstevel@tonic-gate get_rssize(void *lwp)
91*0Sstevel@tonic-gate {
92*0Sstevel@tonic-gate return ((ulong_t)((lwp_info_t *)lwp)->li_info.pr_rssize);
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate static ulong_t
get_pri(void * lwp)96*0Sstevel@tonic-gate get_pri(void *lwp)
97*0Sstevel@tonic-gate {
98*0Sstevel@tonic-gate return ((ulong_t)((lwp_info_t *)lwp)->li_info.pr_lwp.pr_pri);
99*0Sstevel@tonic-gate }
100*0Sstevel@tonic-gate
101*0Sstevel@tonic-gate static ulong_t
get_idkey(void * id)102*0Sstevel@tonic-gate get_idkey(void *id)
103*0Sstevel@tonic-gate {
104*0Sstevel@tonic-gate return (((id_info_t *)id)->id_key);
105*0Sstevel@tonic-gate }
106*0Sstevel@tonic-gate
107*0Sstevel@tonic-gate void
list_setkeyfunc(char * arg,optdesc_t * opt,list_t * list,int type)108*0Sstevel@tonic-gate list_setkeyfunc(char *arg, optdesc_t *opt, list_t *list, int type)
109*0Sstevel@tonic-gate {
110*0Sstevel@tonic-gate if (list == NULL)
111*0Sstevel@tonic-gate return;
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gate list->l_sortorder = opt->o_sortorder;
114*0Sstevel@tonic-gate list->l_type = type;
115*0Sstevel@tonic-gate if (arg == NULL) { /* special case for id_infos */
116*0Sstevel@tonic-gate list->l_func = get_idkey;
117*0Sstevel@tonic-gate return;
118*0Sstevel@tonic-gate }
119*0Sstevel@tonic-gate if (strcmp("cpu", arg) == 0) {
120*0Sstevel@tonic-gate if (opt->o_outpmode & OPT_MSACCT)
121*0Sstevel@tonic-gate list->l_func = get_cpu_from_usage;
122*0Sstevel@tonic-gate else
123*0Sstevel@tonic-gate list->l_func = get_cpu_from_psinfo;
124*0Sstevel@tonic-gate return;
125*0Sstevel@tonic-gate }
126*0Sstevel@tonic-gate if (strcmp("time", arg) == 0) {
127*0Sstevel@tonic-gate list->l_func = get_time;
128*0Sstevel@tonic-gate return;
129*0Sstevel@tonic-gate }
130*0Sstevel@tonic-gate if (strcmp("size", arg) == 0) {
131*0Sstevel@tonic-gate list->l_func = get_size;
132*0Sstevel@tonic-gate return;
133*0Sstevel@tonic-gate }
134*0Sstevel@tonic-gate if (strcmp("rss", arg) == 0) {
135*0Sstevel@tonic-gate list->l_func = get_rssize;
136*0Sstevel@tonic-gate return;
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate if (strcmp("pri", arg) == 0) {
139*0Sstevel@tonic-gate list->l_func = get_pri;
140*0Sstevel@tonic-gate return;
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate Die(gettext("invalid sort key -- %s\n"), arg);
143*0Sstevel@tonic-gate }
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate ulong_t
list_getkeyval(list_t * list,void * ptr)146*0Sstevel@tonic-gate list_getkeyval(list_t *list, void *ptr)
147*0Sstevel@tonic-gate {
148*0Sstevel@tonic-gate return (list->l_func(ptr));
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate static int
compare_keys(list_t * list,ulong_t key1,ulong_t key2)152*0Sstevel@tonic-gate compare_keys(list_t *list, ulong_t key1, ulong_t key2)
153*0Sstevel@tonic-gate {
154*0Sstevel@tonic-gate if (key1 == key2)
155*0Sstevel@tonic-gate return (0);
156*0Sstevel@tonic-gate if (key1 < key2)
157*0Sstevel@tonic-gate return (1 * list->l_sortorder);
158*0Sstevel@tonic-gate else
159*0Sstevel@tonic-gate return (-1 * list->l_sortorder);
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate static void
list_insert(list_t * list,void * ptr)163*0Sstevel@tonic-gate list_insert(list_t *list, void *ptr)
164*0Sstevel@tonic-gate {
165*0Sstevel@tonic-gate int i, j;
166*0Sstevel@tonic-gate long k1, k2;
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate for (i = 0; i < list->l_used; i++) { /* insert in the middle */
169*0Sstevel@tonic-gate k1 = list_getkeyval(list, ptr);
170*0Sstevel@tonic-gate k2 = list_getkeyval(list, list->l_ptrs[i]);
171*0Sstevel@tonic-gate if (compare_keys(list, k1, k2) >= 0) {
172*0Sstevel@tonic-gate for (j = list->l_used - 1; j >= i; j--)
173*0Sstevel@tonic-gate list->l_ptrs[j+1] = list->l_ptrs[j];
174*0Sstevel@tonic-gate list->l_ptrs[i] = ptr;
175*0Sstevel@tonic-gate if (list->l_used < list->l_size)
176*0Sstevel@tonic-gate list->l_used++;
177*0Sstevel@tonic-gate return;
178*0Sstevel@tonic-gate }
179*0Sstevel@tonic-gate }
180*0Sstevel@tonic-gate if (i + 1 <= list->l_size) { /* insert at the tail */
181*0Sstevel@tonic-gate list->l_ptrs[list->l_used] = ptr;
182*0Sstevel@tonic-gate
183*0Sstevel@tonic-gate list->l_used++;
184*0Sstevel@tonic-gate }
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate
187*0Sstevel@tonic-gate static void
list_preinsert(list_t * list,void * ptr)188*0Sstevel@tonic-gate list_preinsert(list_t *list, void *ptr)
189*0Sstevel@tonic-gate {
190*0Sstevel@tonic-gate ulong_t k1, k2;
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate if (list->l_used < list->l_size) { /* just add */
193*0Sstevel@tonic-gate list_insert(list, ptr);
194*0Sstevel@tonic-gate return;
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate k1 = list_getkeyval(list, list->l_ptrs[list->l_used - 1]);
197*0Sstevel@tonic-gate k2 = list_getkeyval(list, ptr);
198*0Sstevel@tonic-gate if (compare_keys(list, k1, k2) >= 0) /* skip insertion */
199*0Sstevel@tonic-gate return;
200*0Sstevel@tonic-gate k1 = list_getkeyval(list, list->l_ptrs[0]);
201*0Sstevel@tonic-gate if (compare_keys(list, k2, k1) >= 0) { /* add at the head */
202*0Sstevel@tonic-gate list_insert(list, ptr);
203*0Sstevel@tonic-gate return;
204*0Sstevel@tonic-gate }
205*0Sstevel@tonic-gate list_insert(list, ptr);
206*0Sstevel@tonic-gate }
207*0Sstevel@tonic-gate
208*0Sstevel@tonic-gate void
list_sort(list_t * list)209*0Sstevel@tonic-gate list_sort(list_t *list)
210*0Sstevel@tonic-gate {
211*0Sstevel@tonic-gate (void) memset(list->l_ptrs, 0, sizeof (void *) * list->l_size);
212*0Sstevel@tonic-gate list->l_used = 0;
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate if (list->l_type == LT_LWPS) {
215*0Sstevel@tonic-gate lwp_info_t *lwp = list->l_head;
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate while (lwp) {
218*0Sstevel@tonic-gate list_preinsert(list, (void *)lwp);
219*0Sstevel@tonic-gate lwp = lwp->li_next;
220*0Sstevel@tonic-gate }
221*0Sstevel@tonic-gate } else {
222*0Sstevel@tonic-gate id_info_t *id = list->l_head;
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate while (id) {
225*0Sstevel@tonic-gate list_preinsert(list, (void *)id);
226*0Sstevel@tonic-gate id = id->id_next;
227*0Sstevel@tonic-gate }
228*0Sstevel@tonic-gate }
229*0Sstevel@tonic-gate }
230