xref: /aosp_15_r20/external/blktrace/btt/seek.c (revision 1a3d31e37cc95e9919fd86900a2b6a555f55952c)
1*1a3d31e3SAndroid Build Coastguard Worker /*
2*1a3d31e3SAndroid Build Coastguard Worker  * blktrace output analysis: generate a timeline & gather statistics
3*1a3d31e3SAndroid Build Coastguard Worker  *
4*1a3d31e3SAndroid Build Coastguard Worker  * Copyright (C) 2006 Alan D. Brunelle <[email protected]>
5*1a3d31e3SAndroid Build Coastguard Worker  *
6*1a3d31e3SAndroid Build Coastguard Worker  *  This program is free software; you can redistribute it and/or modify
7*1a3d31e3SAndroid Build Coastguard Worker  *  it under the terms of the GNU General Public License as published by
8*1a3d31e3SAndroid Build Coastguard Worker  *  the Free Software Foundation; either version 2 of the License, or
9*1a3d31e3SAndroid Build Coastguard Worker  *  (at your option) any later version.
10*1a3d31e3SAndroid Build Coastguard Worker  *
11*1a3d31e3SAndroid Build Coastguard Worker  *  This program is distributed in the hope that it will be useful,
12*1a3d31e3SAndroid Build Coastguard Worker  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*1a3d31e3SAndroid Build Coastguard Worker  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*1a3d31e3SAndroid Build Coastguard Worker  *  GNU General Public License for more details.
15*1a3d31e3SAndroid Build Coastguard Worker  *
16*1a3d31e3SAndroid Build Coastguard Worker  *  You should have received a copy of the GNU General Public License
17*1a3d31e3SAndroid Build Coastguard Worker  *  along with this program; if not, write to the Free Software
18*1a3d31e3SAndroid Build Coastguard Worker  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19*1a3d31e3SAndroid Build Coastguard Worker  *
20*1a3d31e3SAndroid Build Coastguard Worker  */
21*1a3d31e3SAndroid Build Coastguard Worker #include <float.h>
22*1a3d31e3SAndroid Build Coastguard Worker #include "globals.h"
23*1a3d31e3SAndroid Build Coastguard Worker 
24*1a3d31e3SAndroid Build Coastguard Worker struct seek_bkt {
25*1a3d31e3SAndroid Build Coastguard Worker 	struct rb_node rb_node;
26*1a3d31e3SAndroid Build Coastguard Worker 	long long sectors;
27*1a3d31e3SAndroid Build Coastguard Worker 	int nseeks;
28*1a3d31e3SAndroid Build Coastguard Worker };
29*1a3d31e3SAndroid Build Coastguard Worker 
30*1a3d31e3SAndroid Build Coastguard Worker /* Seeks per second */
31*1a3d31e3SAndroid Build Coastguard Worker struct sps_bkt {
32*1a3d31e3SAndroid Build Coastguard Worker 	double t_start, t_last;
33*1a3d31e3SAndroid Build Coastguard Worker 	unsigned long nseeks;
34*1a3d31e3SAndroid Build Coastguard Worker };
35*1a3d31e3SAndroid Build Coastguard Worker 
36*1a3d31e3SAndroid Build Coastguard Worker struct seeki {
37*1a3d31e3SAndroid Build Coastguard Worker 	FILE *rfp, *wfp, *cfp, *sps_fp;
38*1a3d31e3SAndroid Build Coastguard Worker 	struct rb_root root;
39*1a3d31e3SAndroid Build Coastguard Worker 	struct sps_bkt sps;
40*1a3d31e3SAndroid Build Coastguard Worker 	long long tot_seeks;
41*1a3d31e3SAndroid Build Coastguard Worker 	double total_sectors;
42*1a3d31e3SAndroid Build Coastguard Worker 	long long last_start, last_end;
43*1a3d31e3SAndroid Build Coastguard Worker };
44*1a3d31e3SAndroid Build Coastguard Worker 
seek_open(char * str,char rw)45*1a3d31e3SAndroid Build Coastguard Worker static FILE *seek_open(char *str, char rw)
46*1a3d31e3SAndroid Build Coastguard Worker {
47*1a3d31e3SAndroid Build Coastguard Worker 	FILE *fp;
48*1a3d31e3SAndroid Build Coastguard Worker 	char *oname;
49*1a3d31e3SAndroid Build Coastguard Worker 
50*1a3d31e3SAndroid Build Coastguard Worker 	if (seek_name == NULL) return NULL;
51*1a3d31e3SAndroid Build Coastguard Worker 
52*1a3d31e3SAndroid Build Coastguard Worker 	oname = malloc(strlen(seek_name) + strlen(str) + 32);
53*1a3d31e3SAndroid Build Coastguard Worker 	sprintf(oname, "%s_%s_%c.dat", seek_name, str, rw);
54*1a3d31e3SAndroid Build Coastguard Worker 	if ((fp = my_fopen(oname, "w")) == NULL) {
55*1a3d31e3SAndroid Build Coastguard Worker 		perror(oname);
56*1a3d31e3SAndroid Build Coastguard Worker 		free(oname);
57*1a3d31e3SAndroid Build Coastguard Worker 	} else
58*1a3d31e3SAndroid Build Coastguard Worker 		add_file(fp, oname);
59*1a3d31e3SAndroid Build Coastguard Worker 
60*1a3d31e3SAndroid Build Coastguard Worker 	return fp;
61*1a3d31e3SAndroid Build Coastguard Worker }
62*1a3d31e3SAndroid Build Coastguard Worker 
__insert(struct rb_root * root,long long sectors)63*1a3d31e3SAndroid Build Coastguard Worker static void __insert(struct rb_root *root, long long sectors)
64*1a3d31e3SAndroid Build Coastguard Worker {
65*1a3d31e3SAndroid Build Coastguard Worker 	struct seek_bkt *sbp;
66*1a3d31e3SAndroid Build Coastguard Worker 	struct rb_node *parent = NULL;
67*1a3d31e3SAndroid Build Coastguard Worker 	struct rb_node **p = &root->rb_node;
68*1a3d31e3SAndroid Build Coastguard Worker 
69*1a3d31e3SAndroid Build Coastguard Worker 	while (*p) {
70*1a3d31e3SAndroid Build Coastguard Worker 		parent = *p;
71*1a3d31e3SAndroid Build Coastguard Worker 		sbp = rb_entry(parent, struct seek_bkt, rb_node);
72*1a3d31e3SAndroid Build Coastguard Worker 		if (sectors < sbp->sectors)
73*1a3d31e3SAndroid Build Coastguard Worker 			p = &(*p)->rb_left;
74*1a3d31e3SAndroid Build Coastguard Worker 		else if (sectors > sbp->sectors)
75*1a3d31e3SAndroid Build Coastguard Worker 			p = &(*p)->rb_right;
76*1a3d31e3SAndroid Build Coastguard Worker 		else {
77*1a3d31e3SAndroid Build Coastguard Worker 			sbp->nseeks++;
78*1a3d31e3SAndroid Build Coastguard Worker 			return;
79*1a3d31e3SAndroid Build Coastguard Worker 		}
80*1a3d31e3SAndroid Build Coastguard Worker 	}
81*1a3d31e3SAndroid Build Coastguard Worker 
82*1a3d31e3SAndroid Build Coastguard Worker 	sbp = malloc(sizeof(struct seek_bkt));
83*1a3d31e3SAndroid Build Coastguard Worker 	sbp->nseeks = 1;
84*1a3d31e3SAndroid Build Coastguard Worker 	sbp->sectors = sectors;
85*1a3d31e3SAndroid Build Coastguard Worker 
86*1a3d31e3SAndroid Build Coastguard Worker 	rb_link_node(&sbp->rb_node, parent, p);
87*1a3d31e3SAndroid Build Coastguard Worker 	rb_insert_color(&sbp->rb_node, root);
88*1a3d31e3SAndroid Build Coastguard Worker }
89*1a3d31e3SAndroid Build Coastguard Worker 
__destroy(struct rb_node * n)90*1a3d31e3SAndroid Build Coastguard Worker static void __destroy(struct rb_node *n)
91*1a3d31e3SAndroid Build Coastguard Worker {
92*1a3d31e3SAndroid Build Coastguard Worker 	if (n) {
93*1a3d31e3SAndroid Build Coastguard Worker 		struct seek_bkt *sbp = rb_entry(n, struct seek_bkt, rb_node);
94*1a3d31e3SAndroid Build Coastguard Worker 
95*1a3d31e3SAndroid Build Coastguard Worker 		__destroy(n->rb_left);
96*1a3d31e3SAndroid Build Coastguard Worker 		__destroy(n->rb_right);
97*1a3d31e3SAndroid Build Coastguard Worker 		free(sbp);
98*1a3d31e3SAndroid Build Coastguard Worker 	}
99*1a3d31e3SAndroid Build Coastguard Worker }
100*1a3d31e3SAndroid Build Coastguard Worker 
sps_emit(struct seeki * sip)101*1a3d31e3SAndroid Build Coastguard Worker static void sps_emit(struct seeki *sip)
102*1a3d31e3SAndroid Build Coastguard Worker {
103*1a3d31e3SAndroid Build Coastguard Worker 	double s_p_s;
104*1a3d31e3SAndroid Build Coastguard Worker 	struct sps_bkt *sps = &sip->sps;
105*1a3d31e3SAndroid Build Coastguard Worker 	double delta = sps->t_last - sps->t_start;
106*1a3d31e3SAndroid Build Coastguard Worker 
107*1a3d31e3SAndroid Build Coastguard Worker 	if ((sps->nseeks == 1) || (delta < DBL_EPSILON))
108*1a3d31e3SAndroid Build Coastguard Worker 		s_p_s = (double)(sps->nseeks);
109*1a3d31e3SAndroid Build Coastguard Worker 	else
110*1a3d31e3SAndroid Build Coastguard Worker 		s_p_s = (double)(sps->nseeks) / delta;
111*1a3d31e3SAndroid Build Coastguard Worker 
112*1a3d31e3SAndroid Build Coastguard Worker 	fprintf(sip->sps_fp, "%15.9lf %.2lf\n", sps->t_start, s_p_s);
113*1a3d31e3SAndroid Build Coastguard Worker 
114*1a3d31e3SAndroid Build Coastguard Worker 	sps->t_start = 0;
115*1a3d31e3SAndroid Build Coastguard Worker 	sps->nseeks = 0;
116*1a3d31e3SAndroid Build Coastguard Worker }
117*1a3d31e3SAndroid Build Coastguard Worker 
sps_add(struct seeki * sip,double t)118*1a3d31e3SAndroid Build Coastguard Worker static void sps_add(struct seeki *sip, double t)
119*1a3d31e3SAndroid Build Coastguard Worker {
120*1a3d31e3SAndroid Build Coastguard Worker 	if (sip->sps_fp) {
121*1a3d31e3SAndroid Build Coastguard Worker 		struct sps_bkt *sps = &sip->sps;
122*1a3d31e3SAndroid Build Coastguard Worker 
123*1a3d31e3SAndroid Build Coastguard Worker 		if (sps->nseeks != 0 && ((t - sps->t_start) >= 1.0))
124*1a3d31e3SAndroid Build Coastguard Worker 			sps_emit(sip);
125*1a3d31e3SAndroid Build Coastguard Worker 
126*1a3d31e3SAndroid Build Coastguard Worker 		sps->t_last = t;
127*1a3d31e3SAndroid Build Coastguard Worker 		if (sps->nseeks == 0) {
128*1a3d31e3SAndroid Build Coastguard Worker 			sps->t_start = t;
129*1a3d31e3SAndroid Build Coastguard Worker 			sps->nseeks = 1;
130*1a3d31e3SAndroid Build Coastguard Worker 		} else
131*1a3d31e3SAndroid Build Coastguard Worker 			sps->nseeks++;
132*1a3d31e3SAndroid Build Coastguard Worker 	}
133*1a3d31e3SAndroid Build Coastguard Worker }
134*1a3d31e3SAndroid Build Coastguard Worker 
__median(struct rb_node * n,long long sofar,long long target,long long * rvp)135*1a3d31e3SAndroid Build Coastguard Worker static int __median(struct rb_node *n, long long sofar, long long target,
136*1a3d31e3SAndroid Build Coastguard Worker 		    long long *rvp)
137*1a3d31e3SAndroid Build Coastguard Worker {
138*1a3d31e3SAndroid Build Coastguard Worker 	struct seek_bkt *sbp;
139*1a3d31e3SAndroid Build Coastguard Worker 
140*1a3d31e3SAndroid Build Coastguard Worker 	sbp = rb_entry(n, struct seek_bkt, rb_node);
141*1a3d31e3SAndroid Build Coastguard Worker 	if ((sofar + sbp->nseeks) >= target) {
142*1a3d31e3SAndroid Build Coastguard Worker 		*rvp = sbp->sectors;
143*1a3d31e3SAndroid Build Coastguard Worker 		return 1;
144*1a3d31e3SAndroid Build Coastguard Worker 	}
145*1a3d31e3SAndroid Build Coastguard Worker 
146*1a3d31e3SAndroid Build Coastguard Worker 	if (n->rb_left && __median(n->rb_left, sofar, target, rvp))
147*1a3d31e3SAndroid Build Coastguard Worker 		return 1;
148*1a3d31e3SAndroid Build Coastguard Worker 
149*1a3d31e3SAndroid Build Coastguard Worker 	if (n->rb_right && __median(n->rb_right, sofar, target, rvp))
150*1a3d31e3SAndroid Build Coastguard Worker 		return 1;
151*1a3d31e3SAndroid Build Coastguard Worker 
152*1a3d31e3SAndroid Build Coastguard Worker 	return 0;
153*1a3d31e3SAndroid Build Coastguard Worker 
154*1a3d31e3SAndroid Build Coastguard Worker }
155*1a3d31e3SAndroid Build Coastguard Worker 
__mode(struct rb_node * n,struct mode * mp)156*1a3d31e3SAndroid Build Coastguard Worker static void __mode(struct rb_node *n, struct mode *mp)
157*1a3d31e3SAndroid Build Coastguard Worker {
158*1a3d31e3SAndroid Build Coastguard Worker 	struct seek_bkt *sbp;
159*1a3d31e3SAndroid Build Coastguard Worker 
160*1a3d31e3SAndroid Build Coastguard Worker 	if (n->rb_left)
161*1a3d31e3SAndroid Build Coastguard Worker 		__mode(n->rb_left, mp);
162*1a3d31e3SAndroid Build Coastguard Worker 	if (n->rb_right)
163*1a3d31e3SAndroid Build Coastguard Worker 		__mode(n->rb_right, mp);
164*1a3d31e3SAndroid Build Coastguard Worker 
165*1a3d31e3SAndroid Build Coastguard Worker 	sbp = rb_entry(n, struct seek_bkt, rb_node);
166*1a3d31e3SAndroid Build Coastguard Worker 	if (mp->modes == NULL) {
167*1a3d31e3SAndroid Build Coastguard Worker 		mp->modes = malloc(sizeof(long long));
168*1a3d31e3SAndroid Build Coastguard Worker 		mp->nmds = 0;
169*1a3d31e3SAndroid Build Coastguard Worker 	} else if (sbp->nseeks > mp->most_seeks)
170*1a3d31e3SAndroid Build Coastguard Worker 		mp->nmds = 0;
171*1a3d31e3SAndroid Build Coastguard Worker 	else if (sbp->nseeks == mp->most_seeks)
172*1a3d31e3SAndroid Build Coastguard Worker 		mp->modes = realloc(mp->modes, (mp->nmds + 1) *
173*1a3d31e3SAndroid Build Coastguard Worker 							sizeof(long long));
174*1a3d31e3SAndroid Build Coastguard Worker 	else
175*1a3d31e3SAndroid Build Coastguard Worker 		return;
176*1a3d31e3SAndroid Build Coastguard Worker 
177*1a3d31e3SAndroid Build Coastguard Worker 	mp->most_seeks = sbp->nseeks;
178*1a3d31e3SAndroid Build Coastguard Worker 	mp->modes[mp->nmds++] = sbp->sectors;
179*1a3d31e3SAndroid Build Coastguard Worker }
180*1a3d31e3SAndroid Build Coastguard Worker 
seek_dist(struct seeki * sip,struct io * iop)181*1a3d31e3SAndroid Build Coastguard Worker long long seek_dist(struct seeki *sip, struct io *iop)
182*1a3d31e3SAndroid Build Coastguard Worker {
183*1a3d31e3SAndroid Build Coastguard Worker 	long long dist;
184*1a3d31e3SAndroid Build Coastguard Worker 	long long start = BIT_START(iop), end = BIT_END(iop);
185*1a3d31e3SAndroid Build Coastguard Worker 
186*1a3d31e3SAndroid Build Coastguard Worker 	if (seek_absolute)
187*1a3d31e3SAndroid Build Coastguard Worker 		dist = start - sip->last_end;
188*1a3d31e3SAndroid Build Coastguard Worker 	else {
189*1a3d31e3SAndroid Build Coastguard Worker 		/* Some overlap means no seek */
190*1a3d31e3SAndroid Build Coastguard Worker 		if (((sip->last_start <= start) && (start <= sip->last_end)) ||
191*1a3d31e3SAndroid Build Coastguard Worker 		    ((sip->last_start <= end) && (end <= sip->last_end)))
192*1a3d31e3SAndroid Build Coastguard Worker 			dist = 0;
193*1a3d31e3SAndroid Build Coastguard Worker 		else if (start > sip->last_end)
194*1a3d31e3SAndroid Build Coastguard Worker 			dist = start - sip->last_end;
195*1a3d31e3SAndroid Build Coastguard Worker 		else
196*1a3d31e3SAndroid Build Coastguard Worker 			dist = start - sip->last_start;
197*1a3d31e3SAndroid Build Coastguard Worker 
198*1a3d31e3SAndroid Build Coastguard Worker 	}
199*1a3d31e3SAndroid Build Coastguard Worker 
200*1a3d31e3SAndroid Build Coastguard Worker 	sip->last_start = start;
201*1a3d31e3SAndroid Build Coastguard Worker 	sip->last_end = end;
202*1a3d31e3SAndroid Build Coastguard Worker 	return dist;
203*1a3d31e3SAndroid Build Coastguard Worker }
204*1a3d31e3SAndroid Build Coastguard Worker 
seeki_alloc(struct d_info * dip,char * post)205*1a3d31e3SAndroid Build Coastguard Worker void *seeki_alloc(struct d_info *dip, char *post)
206*1a3d31e3SAndroid Build Coastguard Worker {
207*1a3d31e3SAndroid Build Coastguard Worker 	char str[256];
208*1a3d31e3SAndroid Build Coastguard Worker 	struct seeki *sip = malloc(sizeof(struct seeki));
209*1a3d31e3SAndroid Build Coastguard Worker 
210*1a3d31e3SAndroid Build Coastguard Worker 	sprintf(str, "%s%s", dip->dip_name, post);
211*1a3d31e3SAndroid Build Coastguard Worker 	sip->rfp = seek_open(str, 'r');
212*1a3d31e3SAndroid Build Coastguard Worker 	sip->wfp = seek_open(str, 'w');
213*1a3d31e3SAndroid Build Coastguard Worker 	sip->cfp = seek_open(str, 'c');
214*1a3d31e3SAndroid Build Coastguard Worker 	sip->tot_seeks = 0;
215*1a3d31e3SAndroid Build Coastguard Worker 	sip->total_sectors = 0.0;
216*1a3d31e3SAndroid Build Coastguard Worker 	sip->last_start = sip->last_end = 0;
217*1a3d31e3SAndroid Build Coastguard Worker 	memset(&sip->root, 0, sizeof(sip->root));
218*1a3d31e3SAndroid Build Coastguard Worker 
219*1a3d31e3SAndroid Build Coastguard Worker 	if (sps_name) {
220*1a3d31e3SAndroid Build Coastguard Worker 		char *oname;
221*1a3d31e3SAndroid Build Coastguard Worker 
222*1a3d31e3SAndroid Build Coastguard Worker 		memset(&sip->sps, 0, sizeof(sip->sps));
223*1a3d31e3SAndroid Build Coastguard Worker 
224*1a3d31e3SAndroid Build Coastguard Worker 		oname = malloc(strlen(sps_name) + strlen(dip->dip_name) + 32);
225*1a3d31e3SAndroid Build Coastguard Worker 		sprintf(oname, "%s_%s.dat", sps_name, dip->dip_name);
226*1a3d31e3SAndroid Build Coastguard Worker 		if ((sip->sps_fp = my_fopen(oname, "w")) == NULL) {
227*1a3d31e3SAndroid Build Coastguard Worker 			perror(oname);
228*1a3d31e3SAndroid Build Coastguard Worker 			free(oname);
229*1a3d31e3SAndroid Build Coastguard Worker 		} else
230*1a3d31e3SAndroid Build Coastguard Worker 			add_file(sip->sps_fp, oname);
231*1a3d31e3SAndroid Build Coastguard Worker 	} else
232*1a3d31e3SAndroid Build Coastguard Worker 		sip->sps_fp = NULL;
233*1a3d31e3SAndroid Build Coastguard Worker 
234*1a3d31e3SAndroid Build Coastguard Worker 	return sip;
235*1a3d31e3SAndroid Build Coastguard Worker }
236*1a3d31e3SAndroid Build Coastguard Worker 
seeki_free(void * param)237*1a3d31e3SAndroid Build Coastguard Worker void seeki_free(void *param)
238*1a3d31e3SAndroid Build Coastguard Worker {
239*1a3d31e3SAndroid Build Coastguard Worker 	struct seeki *sip = param;
240*1a3d31e3SAndroid Build Coastguard Worker 
241*1a3d31e3SAndroid Build Coastguard Worker 	if (sip->sps_fp && sip->sps.nseeks != 0)
242*1a3d31e3SAndroid Build Coastguard Worker 		sps_emit(sip);
243*1a3d31e3SAndroid Build Coastguard Worker 
244*1a3d31e3SAndroid Build Coastguard Worker 	/*
245*1a3d31e3SAndroid Build Coastguard Worker 	 * Associated files are cleaned up by seek_clean
246*1a3d31e3SAndroid Build Coastguard Worker 	 */
247*1a3d31e3SAndroid Build Coastguard Worker 	__destroy(sip->root.rb_node);
248*1a3d31e3SAndroid Build Coastguard Worker 	free(sip);
249*1a3d31e3SAndroid Build Coastguard Worker }
250*1a3d31e3SAndroid Build Coastguard Worker 
seeki_add(void * handle,struct io * iop)251*1a3d31e3SAndroid Build Coastguard Worker void seeki_add(void *handle, struct io *iop)
252*1a3d31e3SAndroid Build Coastguard Worker {
253*1a3d31e3SAndroid Build Coastguard Worker 	struct seeki *sip = handle;
254*1a3d31e3SAndroid Build Coastguard Worker 	char rw = IOP_READ(iop) ? 'r' : 'w';
255*1a3d31e3SAndroid Build Coastguard Worker 	long long dist = seek_dist(sip, iop);
256*1a3d31e3SAndroid Build Coastguard Worker 	double tstamp = BIT_TIME(iop->t.time);
257*1a3d31e3SAndroid Build Coastguard Worker 	FILE *fp = IOP_READ(iop) ? sip->rfp : sip->wfp;
258*1a3d31e3SAndroid Build Coastguard Worker 
259*1a3d31e3SAndroid Build Coastguard Worker 	if (fp)
260*1a3d31e3SAndroid Build Coastguard Worker 		fprintf(fp, "%15.9lf %13lld %c\n", tstamp, dist, rw);
261*1a3d31e3SAndroid Build Coastguard Worker 	if (sip->cfp)
262*1a3d31e3SAndroid Build Coastguard Worker 		fprintf(sip->cfp, "%15.9lf %13lld %c\n", tstamp, dist, rw);
263*1a3d31e3SAndroid Build Coastguard Worker 
264*1a3d31e3SAndroid Build Coastguard Worker 	dist = llabs(dist);
265*1a3d31e3SAndroid Build Coastguard Worker 	sip->tot_seeks++;
266*1a3d31e3SAndroid Build Coastguard Worker 	sip->total_sectors += dist;
267*1a3d31e3SAndroid Build Coastguard Worker 	__insert(&sip->root, dist);
268*1a3d31e3SAndroid Build Coastguard Worker 
269*1a3d31e3SAndroid Build Coastguard Worker 	sps_add(sip, tstamp);
270*1a3d31e3SAndroid Build Coastguard Worker }
271*1a3d31e3SAndroid Build Coastguard Worker 
seeki_nseeks(void * handle)272*1a3d31e3SAndroid Build Coastguard Worker long long seeki_nseeks(void *handle)
273*1a3d31e3SAndroid Build Coastguard Worker {
274*1a3d31e3SAndroid Build Coastguard Worker 	return ((struct seeki *)handle)->tot_seeks;
275*1a3d31e3SAndroid Build Coastguard Worker }
276*1a3d31e3SAndroid Build Coastguard Worker 
seeki_mean(void * handle)277*1a3d31e3SAndroid Build Coastguard Worker double seeki_mean(void *handle)
278*1a3d31e3SAndroid Build Coastguard Worker {
279*1a3d31e3SAndroid Build Coastguard Worker 	struct seeki *sip = handle;
280*1a3d31e3SAndroid Build Coastguard Worker 	return sip->total_sectors / sip->tot_seeks;
281*1a3d31e3SAndroid Build Coastguard Worker }
282*1a3d31e3SAndroid Build Coastguard Worker 
seeki_median(void * handle)283*1a3d31e3SAndroid Build Coastguard Worker long long seeki_median(void *handle)
284*1a3d31e3SAndroid Build Coastguard Worker {
285*1a3d31e3SAndroid Build Coastguard Worker 	long long rval = 0LL;
286*1a3d31e3SAndroid Build Coastguard Worker 	struct seeki *sip = handle;
287*1a3d31e3SAndroid Build Coastguard Worker 
288*1a3d31e3SAndroid Build Coastguard Worker 	if (sip->root.rb_node)
289*1a3d31e3SAndroid Build Coastguard Worker 		(void)__median(sip->root.rb_node, 0LL, sip->tot_seeks / 2,
290*1a3d31e3SAndroid Build Coastguard Worker 			       &rval);
291*1a3d31e3SAndroid Build Coastguard Worker 
292*1a3d31e3SAndroid Build Coastguard Worker 	return rval;
293*1a3d31e3SAndroid Build Coastguard Worker }
294*1a3d31e3SAndroid Build Coastguard Worker 
seeki_mode(void * handle,struct mode * mp)295*1a3d31e3SAndroid Build Coastguard Worker int seeki_mode(void *handle, struct mode *mp)
296*1a3d31e3SAndroid Build Coastguard Worker {
297*1a3d31e3SAndroid Build Coastguard Worker 	struct seeki *sip = handle;
298*1a3d31e3SAndroid Build Coastguard Worker 	struct rb_root *root = &sip->root;
299*1a3d31e3SAndroid Build Coastguard Worker 
300*1a3d31e3SAndroid Build Coastguard Worker 	memset(mp, 0, sizeof(struct mode));
301*1a3d31e3SAndroid Build Coastguard Worker 	if (root->rb_node)
302*1a3d31e3SAndroid Build Coastguard Worker 		__mode(root->rb_node, mp);
303*1a3d31e3SAndroid Build Coastguard Worker 
304*1a3d31e3SAndroid Build Coastguard Worker 	return mp->nmds;
305*1a3d31e3SAndroid Build Coastguard Worker }
306