1 /* 2 * Copyright 2019 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.perfmark.impl; 18 19 /** 20 * A Generator keeps track of what generation the PerfMark library is on. A generation is a way to 21 * group PerfMark recorded tasks and links together. This allows dynamically enabling and disabling 22 * PerfMark. Each time the library is enabled, a new generation is started and associated with all 23 * the recorded data. 24 * 25 * <p>This class is not threadsafe. Synchronization is handled externally. 26 * 27 * <p>Normal users are not expected to use this class. 28 */ 29 public abstract class Generator { 30 /** 31 * This field is here as a hack. This class is a shared dependency of both {@link 32 * SecretPerfMarkImpl} and {@link Storage}. The impl needs to record the first time an event 33 * occurs, but doesn't call Storage#clinit until PerfMark is enabled. This leads to the timings 34 * being off in the trace event viewer, since the "start" time is since it was enabled, rather 35 * than when the first PerfMark call happens. 36 */ 37 static final long INIT_NANO_TIME = System.nanoTime(); 38 39 /** 40 * This field is also here as a hack, capturing the time the program stated. 41 */ 42 static final long INIT_CURRENT_TIME_MILLIS = System.currentTimeMillis(); 43 44 /** 45 * The number of reserved bits at the bottom of the generation. All generations should be 46 * left-shifted by this amount. 47 */ 48 public static final int GEN_OFFSET = 8; 49 /** 50 * Represents a failure to enable PerfMark library. This can be used by subclasses to indicate a 51 * previous failure to set the generation. It can also be used to indicate the generation count 52 * has overflowed. 53 */ 54 public static final long FAILURE = -2L << GEN_OFFSET; 55 Generator()56 protected Generator() {} 57 58 /** 59 * Sets the current generation count. This should be eventually noticeable for callers of {@link 60 * #getGeneration()}. An odd number means the library is enabled, while an even number means the 61 * library is disabled. 62 * 63 * @param generation the generation id, shifted left by {@link #GEN_OFFSET}. 64 */ setGeneration(long generation)65 public abstract void setGeneration(long generation); 66 67 /** 68 * Gets the current generation, shifted left by {@link #GEN_OFFSET}. An odd number means the 69 * library is enabled, while an even number means the library is disabled. 70 * 71 * @return the current generation or {@link #FAILURE}. 72 */ getGeneration()73 public abstract long getGeneration(); 74 75 /** 76 * Returns the approximate cost to change the generation. 77 * 78 * @return an approximate number of nanoseconds needed to change the generator value. 79 */ costOfSetNanos()80 public long costOfSetNanos() { 81 return 1000000; 82 } 83 84 /** 85 * Returns the approximate cost to read the generation. 86 * 87 * @return an approximate number of nanoseconds needed to read the generator value. 88 */ costOfGetNanos()89 public long costOfGetNanos() { 90 return 10; 91 } 92 } 93