1 | /* $Id$ $Revision$ */ |
---|---|
2 | /* vim:set shiftwidth=4 ts=8: */ |
3 | |
4 | /************************************************************************* |
5 | * Copyright (c) 2011 AT&T Intellectual Property |
6 | * All rights reserved. This program and the accompanying materials |
7 | * are made available under the terms of the Eclipse Public License v1.0 |
8 | * which accompanies this distribution, and is available at |
9 | * http://www.eclipse.org/legal/epl-v10.html |
10 | * |
11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ |
12 | *************************************************************************/ |
13 | |
14 | #include "vmhdr.h" |
15 | |
16 | /* Get statistics from a region. |
17 | ** |
18 | ** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94. |
19 | */ |
20 | |
21 | int vmstat(Vmalloc_t * vm, Vmstat_t * st) |
22 | { |
23 | reg Seg_t *seg; |
24 | reg Block_t *b, *endb; |
25 | reg size_t s = 0; |
26 | reg Vmdata_t *vd = vm->data; |
27 | |
28 | if (!st) |
29 | return -1; |
30 | if (!(vd->mode & VM_TRUST)) { |
31 | if (ISLOCK(vd, 0)) |
32 | return -1; |
33 | SETLOCK(vd, 0); |
34 | } |
35 | |
36 | st->n_busy = st->n_free = 0; |
37 | st->s_busy = st->s_free = st->m_busy = st->m_free = 0; |
38 | st->n_seg = 0; |
39 | st->extent = 0; |
40 | |
41 | if (vd->mode & VM_MTLAST) |
42 | st->n_busy = 0; |
43 | else if ((vd->mode & VM_MTPOOL) && (s = vd->pool) > 0) { |
44 | s = ROUND(s, ALIGN); |
45 | for (b = vd->free; b; b = SEGLINK(b)) |
46 | st->n_free += 1; |
47 | } |
48 | |
49 | for (seg = vd->seg; seg; seg = seg->next) { |
50 | st->n_seg += 1; |
51 | st->extent += seg->extent; |
52 | |
53 | b = SEGBLOCK(seg); |
54 | endb = BLOCK(seg->baddr); |
55 | |
56 | if (vd->mode & (VM_MTDEBUG | VM_MTBEST | VM_MTPROFILE)) { |
57 | while (b < endb) { |
58 | s = SIZE(b) & ~BITS; |
59 | if (ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b))) { |
60 | if (s > st->m_free) |
61 | st->m_free = s; |
62 | st->s_free += s; |
63 | st->n_free += 1; |
64 | } else { /* get the real size */ |
65 | if (vd->mode & VM_MTDEBUG) |
66 | s = DBSIZE(DB2DEBUG(DATA(b))); |
67 | else if (vd->mode & VM_MTPROFILE) |
68 | s = PFSIZE(DATA(b)); |
69 | if (s > st->m_busy) |
70 | st->m_busy = s; |
71 | st->s_busy += s; |
72 | st->n_busy += 1; |
73 | } |
74 | |
75 | b = (Block_t *) ((Vmuchar_t *) DATA(b) + |
76 | (SIZE(b) & ~BITS)); |
77 | } |
78 | } else if (vd->mode & VM_MTLAST) { |
79 | if ((s = |
80 | seg->free ? (SIZE(seg->free) + sizeof(Head_t)) : 0) > 0) { |
81 | st->s_free += s; |
82 | st->n_free += 1; |
83 | } |
84 | if ((s = ((char *) endb - (char *) b) - s) > 0) { |
85 | st->s_busy += s; |
86 | st->n_busy += 1; |
87 | } |
88 | } else if ((vd->mode & VM_MTPOOL) && s > 0) { |
89 | if (seg->free) |
90 | st->n_free += (SIZE(seg->free) + sizeof(Head_t)) / s; |
91 | st->n_busy += |
92 | ((seg->baddr - (Vmuchar_t *) b) - sizeof(Head_t)) / s; |
93 | } |
94 | } |
95 | |
96 | if ((vd->mode & VM_MTPOOL) && s > 0) { |
97 | st->n_busy -= st->n_free; |
98 | if (st->n_busy > 0) |
99 | st->s_busy = (st->m_busy = vd->pool) * st->n_busy; |
100 | if (st->n_free > 0) |
101 | st->s_free = (st->m_free = vd->pool) * st->n_free; |
102 | } |
103 | |
104 | CLRLOCK(vd, 0); |
105 | return 0; |
106 | } |
107 |