1/*
2 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.jvmstat.perfdata.monitor.v1_0;
27
28import sun.jvmstat.monitor.*;
29import sun.jvmstat.perfdata.monitor.*;
30import java.nio.*;
31
32/**
33 * Class representing the 1.0 version of the HotSpot PerfData instrumentation
34 * buffer header.
35 * <p>
36 * The PerfDataBufferPrologue2_0 class supports parsing of the version
37 * specific portions of the PerfDataPrologue C structure:
38 * <pre>
39 * typedef struct {
40 *   ...                      // handled by superclass
41 *   jint used;               // number of PerfData memory bytes used
42 *   jint overflow;           // number of bytes of overflow
43 *   jlong mod_time_stamp;    // time stamp of the last structural modification
44 * } PerfDataPrologue
45 * </pre>
46 *
47 * @author Brian Doherty
48 * @since 1.5
49 */
50public class PerfDataBufferPrologue extends AbstractPerfDataBufferPrologue {
51
52    private static final int SUPPORTED_MAJOR_VERSION = 1;
53    private static final int SUPPORTED_MINOR_VERSION = 0;
54
55    /*
56     * the following constants must match the field offsets and sizes
57     * in the PerfDataPrologue structure in perfMemory.hpp
58     */
59    final static int PERFDATA_PROLOG_USED_OFFSET=8;
60    final static int PERFDATA_PROLOG_USED_SIZE=4;              // sizeof(int)
61    final static int PERFDATA_PROLOG_OVERFLOW_OFFSET=12;
62    final static int PERFDATA_PROLOG_OVERFLOW_SIZE=4;          // sizeof(int)
63    final static int PERFDATA_PROLOG_MODTIMESTAMP_OFFSET=16;
64    final static int PERFDATA_PROLOG_MODTIMESTAMP_SIZE=8;      // sizeof(long)
65    final static int PERFDATA_PROLOG_SIZE=24;  // sizeof(struct PerfDataProlog)
66
67    // counter names for prologue psuedo counters
68    final static String PERFDATA_BUFFER_SIZE_NAME  = "sun.perfdata.size";
69    final static String PERFDATA_BUFFER_USED_NAME  = "sun.perfdata.used";
70    final static String PERFDATA_OVERFLOW_NAME     = "sun.perfdata.overflow";
71    final static String PERFDATA_MODTIMESTAMP_NAME = "sun.perfdata.timestamp";
72
73    /**
74     * Create an instance of PerfDataBufferPrologue from the given
75     * ByteBuffer object.
76     *
77     * @param byteBuffer the buffer containing the binary header data
78     */
79    public PerfDataBufferPrologue(ByteBuffer byteBuffer)
80           throws MonitorException  {
81        super(byteBuffer);
82        assert ((getMajorVersion() == 1) && (getMinorVersion() == 0));
83    }
84
85    /**
86     * {@inheritDoc}
87     */
88    public boolean supportsAccessible() {
89        return false;
90    }
91
92    /**
93     * {@inheritDoc}
94     */
95    public boolean isAccessible() {
96        return true;
97    }
98
99    /**
100     * Get the utilization of the instrumentation memory buffer.
101     *
102     * @return int - the utilization of the buffer
103     */
104    public int getUsed() {
105        byteBuffer.position(PERFDATA_PROLOG_USED_OFFSET);
106        return byteBuffer.getInt();
107    }
108
109    /**
110     * Get the size of the instrumentation memory buffer.
111     *
112     * @return int - the size of the buffer
113     */
114    public int getBufferSize() {
115        return byteBuffer.capacity();
116    }
117
118    /**
119     * Get the buffer overflow amount. This value is non-zero if the
120     * HotSpot JVM has overflowed the instrumentation memory buffer.
121     * The target JVM can be restarted with -XX:PerfDataMemSize=X to
122     * create a larger memory buffer.
123     *
124     * @return int - the size of the buffer
125     */
126    public int getOverflow() {
127        byteBuffer.position(PERFDATA_PROLOG_OVERFLOW_OFFSET);
128        return byteBuffer.getInt();
129    }
130
131    /**
132     * Get the time of last modification for the instrumentation
133     * memory buffer. This method returns the time, as ticks since the
134     * start of the target JVM, of the last structural modification to
135     * the instrumentation buffer. Structural modifications correspond to
136     * the addition or deletion of instrumentation objects. Updates to
137     * counter values are not structural modifications.
138     */
139    public long getModificationTimeStamp() {
140        byteBuffer.position(PERFDATA_PROLOG_MODTIMESTAMP_OFFSET);
141        return byteBuffer.getLong();
142    }
143
144    /**
145     * {@inheritDoc}
146     */
147    public int getSize() {
148        return PERFDATA_PROLOG_SIZE;  // sizeof(struct PerfDataProlog)
149    }
150
151    /**
152     * Return an IntBuffer that accesses the used value. This is used
153     * to create a Monitor object for this value.
154     *
155     * @return IntBuffer - a ByteBuffer that accesses the used value
156     *                     in the instrumentation buffer header.
157     * @see #getUsed()
158     */
159    public IntBuffer usedBuffer() {
160        byteBuffer.position(PERFDATA_PROLOG_USED_OFFSET);
161        IntBuffer ib = byteBuffer.asIntBuffer();
162        ib.limit(1);
163        return ib;
164    }
165
166    /**
167     * Return an IntBuffer that accesses the size value. This is used
168     * to create a Monitor object for this value.
169     *
170     * @return IntBuffer - a ByteBuffer that accesses the size value
171     *                     in the instrumentation buffer header.
172     * @see #getBufferSize()
173     */
174    public IntBuffer sizeBuffer() {
175        IntBuffer ib = IntBuffer.allocate(1);
176        ib.put(byteBuffer.capacity());
177        return ib;
178    }
179
180    /**
181     * Return an IntBuffer that accesses the overflow value. This is used
182     * to create a Monitor object for this value.
183     *
184     * @return IntBuffer - a ByteBuffer that accesses the overflow value
185     *                     in the instrumentation buffer header.
186     * @see #getOverflow()
187     */
188    public IntBuffer overflowBuffer() {
189        byteBuffer.position(PERFDATA_PROLOG_OVERFLOW_OFFSET);
190        IntBuffer ib = byteBuffer.asIntBuffer();
191        ib.limit(1);
192        return ib;
193    }
194
195    /**
196     * Return an LongBuffer that accesses the modification timestamp value.
197     * This is used* to create a Monitor object for this value.
198     *
199     * @return LongBuffer - a ByteBuffer that accesses the modification time
200     *                      stamp value in the instrumentation buffer header.
201     * @see #getModificationTimeStamp()
202     */
203    public LongBuffer modificationTimeStampBuffer() {
204        byteBuffer.position(PERFDATA_PROLOG_MODTIMESTAMP_OFFSET);
205        LongBuffer lb = byteBuffer.asLongBuffer();
206        lb.limit(1);
207        return lb;
208    }
209}
210