00001 /* 00002 * System.hpp 00003 * 00004 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Oracle is a registered trademarks of Oracle Corporation and/or its 00007 * affiliates. 00008 * 00009 * This software is the confidential and proprietary information of Oracle 00010 * Corporation. You shall not disclose such confidential and proprietary 00011 * information and shall use it only in accordance with the terms of the 00012 * license agreement you entered into with Oracle. 00013 * 00014 * This notice may not be removed or altered. 00015 */ 00016 #ifndef COH_SYSTEM_HPP 00017 #define COH_SYSTEM_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/abstract_spec.hpp" 00022 #include "coherence/lang/HeapAnalyzer.hpp" 00023 #include "coherence/lang/ObjectArray.hpp" 00024 #include "coherence/lang/String.hpp" 00025 00026 COH_OPEN_NAMESPACE2(coherence,lang) 00027 00028 00029 /** 00030 * A collection of general purpose utility methods. 00031 * 00032 * @author mf 2007.12.19 00033 */ 00034 class COH_EXPORT System 00035 : public abstract_spec<System> 00036 { 00037 // ----- constructors --------------------------------------------------- 00038 00039 private: 00040 /** 00041 * Blocked constructor. 00042 */ 00043 System(); 00044 00045 00046 // ----- System interface ----------------------------------------------- 00047 00048 public: 00049 /** 00050 * Return the number of milliseconds which have elapsed since the 00051 * process was started. 00052 * 00053 * @return the number of milliseconds which have elapsed since the 00054 * process was started 00055 */ 00056 static int64_t upTimeMillis(); 00057 00058 /** 00059 * Return the elapsed milliseconds since midnight January 1, 1970 UTC. 00060 * 00061 * This function does not guard against the clock rolling back or 00062 * jumping forward. 00063 * 00064 * @return the elapsed milliseconds 00065 */ 00066 static int64_t currentTimeMillis(); 00067 00068 /** 00069 * Returns a "safe" current time in milliseconds. 00070 * 00071 * Unlike the #currentTimeMillis() this method guarantees that the 00072 * time never "goes back". 00073 * 00074 * More specifically, when called twice on the same thread, the second 00075 * call will never return a value that is less then the value returned 00076 * by the first call. If a system time correction becomes necessary, an 00077 * attempt will be made to gradually compensate the returned value, so 00078 * in the long run the value returned by this method is the same as the 00079 * system time. 00080 * 00081 * Additionally, the following always holds true: 00082 * <pre> 00083 * System::safeTimeMillis() >= System::currentTimeMillis(); 00084 * </pre> 00085 * 00086 * @return the difference, measured in milliseconds, between 00087 * the corrected current time and midnight, January 1, 1970 UTC. 00088 */ 00089 static int64_t safeTimeMillis(); 00090 00091 /** 00092 * Returns the last "safe" time as computed by a previous call to 00093 * the {@link #safeTimeMillis} method. 00094 * <p/> 00095 * Note: Since the underlying field is non-volatile, the returned value 00096 * is only guaranteed to be no less than the last value returned by 00097 * safeTimeMillis() call on the same thread. 00098 * 00099 * @return the last "safe" time in milliseconds 00100 */ 00101 static int64_t lastSafeTimeMillis(); 00102 00103 /** 00104 * Return the value of a system property. 00105 * 00106 * The standard naming convention for system properties is '.' 00107 * Separated property names, such as "tangosol.coherence.setting". 00108 * 00109 * As of Coherence 3.4 the only source for system properties is 00110 * environment variables. As some environemts do not allow '.' in 00111 * variable names, a failed lookup will be automatically re-issued 00112 * using a camel-cased version of the supplied name, i.e. the property 00113 * name "tangosol.coherence.setting" would translated to 00114 * "TangosolCoherenceSetting". From a code level perspective 00115 * camel-case does not need to be a consideration, it is only when 00116 * setting environment variables that it may be needed. 00117 * 00118 * @param vsName the name of the property to return 00119 * @param vsDefault the default value for the property 00120 * 00121 * @return the corresponding property value, or the supplied default if 00122 * no value could be found 00123 */ 00124 static String::View getProperty(String::View vsName, 00125 String::View vsDefault = String::NULL_STRING); 00126 00127 /** 00128 * Return the same hash code for the given object as would be returned 00129 * by the default implementation provided in Object. In the case of 00130 * NULL zero is returned. 00131 * 00132 * @param v the object to hash 00133 * 00134 * @return the object's identity hash code. 00135 */ 00136 static size32_t identityHashCode(Object::View v); 00137 00138 /** 00139 * Specify the system interrupt resolution. 00140 * 00141 * The resolution at which a blocked thread will test if it has been 00142 * interrupted. Not all blocking states are guaranteed to utilize this 00143 * feature, but at a minimum Object::wait(), and Coherence based network 00144 * communications do respect this setting. 00145 * 00146 * Once in a blocking state the blocked call may not see updates to this 00147 * setting. If this setting is to be updated it is recommended that it 00148 * only occur once at application startup. 00149 * 00150 * Recommended values are between 100 and 1000 milliseconds, default is 00151 * 250 milliseconds. 00152 * 00153 * @param cMillis the new interrupt resolution 00154 * 00155 * @throws IllegalArgumentException if cMillis <= 0 00156 */ 00157 static void setInterruptResolution(int64_t cMillis); 00158 00159 /** 00160 * Return the interrupt resolution. 00161 * 00162 * @return the interrupt resolution. 00163 */ 00164 static int64_t getInterruptResolution(); 00165 00166 /** 00167 * Load the specified library. 00168 */ 00169 static void loadLibrary(String::View vsLibName); 00170 00171 // ----- diagnostics methods -------------------------------------------- 00172 00173 public: 00174 /** 00175 * Test that the attach count on the Object is the expected value. 00176 * 00177 * This method is for testing purposes only, and will throw an 00178 * exception if the count is not the expected value. 00179 * 00180 * @param v the Object to test 00181 * @param cHandle the expected number of handles attached to this 00182 * Object 00183 * @param fEscaped the expected object escape state 00184 */ 00185 static void assertAttachCount(Object::View v, uint32_t cHandle, 00186 uint32_t cView); 00187 00188 /** 00189 * Return a string representation of the Object's life-cycle state. 00190 * 00191 * This is intended for diagnostics purposes only. 00192 * 00193 * @param v the Object to describe 00194 * 00195 * @return a human-readable description of the object's life-cycle 00196 * state 00197 */ 00198 static String::View getLifeCycleDescription(Object::View v); 00199 00200 /** 00201 * Return the System HeapAnalyzer. 00202 * 00203 * There may be only one HeapAnalyzer for the life of the process, the 00204 * default being the ObjectCountHeapAnalyzer, which is very low cost. 00205 * 00206 * The HeapAnalyzer to use may be specified via the 00207 * "tangosol.coherence.heap.analyzer" system property, can can be set 00208 * to either a registered class name, or to "none". 00209 * 00210 * If using a heap-analyzer other then the default, some Objects 00211 * created during static initialization may not be registered. 00212 * 00213 * @return the System HeapAnalyzer. 00214 */ 00215 static HeapAnalyzer::Handle getHeapAnalyzer(); 00216 00217 /** 00218 * Return the common monitor associated with the specified integer 00219 * value. 00220 * 00221 * Common monitors allow for a low-cost means to reduce contention by 00222 * spreading synchronization over a large number of monitors. An 00223 * example usage would be to produce an "atomic array". For instance 00224 * to atomically change an element within an array which is being 00225 * simultaneously updated by multiple threads: 00226 * <pre> 00227 * COH_SYNCHRONIZED (System::getCommonMonitor( 00228 * System::identityHashCode(aoShared) + i)) 00229 * { 00230 * oOld = haoShared[i]; 00231 * haoShared[i] = oNew; 00232 * } 00233 * </pre> 00234 * With this approach many threads may concurrently access various 00235 * array elements without having to synchronize on the array itself, 00236 * and contend with each other. The use of common monitors also avoids 00237 * the overhead of allocating a unique monitor per index. This example 00238 * additionally makes use of the array's identity hash code to avoid 00239 * frequent collisions against other atomic arrays for the same indices. 00240 * <p/> 00241 * As they are shared, these monitors will apply to any number of 00242 * unrelated entities, and as such certain precautions must be employed 00243 * when using them. 00244 * <ul> 00245 * <li>The holder of a common monitor MUST not synchronize on any other 00246 * common monitor. Failure to adhere to this precaution will result 00247 * in a deadlock. 00248 * <li>Notifications on a common monitor MUST use notifyAll() rather 00249 * then notify(), as there may be unrelated threads waiting for 00250 * notification on the same monitor which could consume a single 00251 * notification. Thus the only way to ensure that the desired 00252 * thread does receive notification is to notify all threads 00253 * waiting on the monitor. 00254 * <li>Threads waiting for a notification must protect themselves 00255 * against spurious style wakeups. While this is a general, though 00256 * often overlooked part of the normal use of notification, with 00257 * common monitors it is far more likely that a thread will be 00258 * notified due to an unrelated event. 00259 * <li>A thread which is holding synchronization on a common monitor 00260 * should avoid blocking operations as this could block unrelated 00261 * threads which happen to be utilizing the same common monitor. 00262 * </ul> 00263 * The ideal number of common monitors in a process is one per 00264 * concurrently executing thread. As this number is generally unknown 00265 * the default number of monitors set to a relatively high value. The 00266 * value may also be manually specified via the 00267 * <code>tangosol.coherence.commonmonitors</code> system property. 00268 * 00269 * @param i the common monitor identifier 00270 * 00271 * @return the associated monitor 00272 */ 00273 static Object::Handle getCommonMonitor(size32_t i); 00274 00275 /** 00276 * Return the common monitor associated with the specified long value. 00277 * 00278 * @param l the common monitor identifier 00279 * 00280 * @return the associated monitor 00281 * 00282 * @see #getCommonMonitor(size32_t) 00283 */ 00284 static Object::Handle getCommonMonitor(size64_t l); 00285 00286 /** 00287 * Return a random common monitor for use as the guardian of 00288 * thread-safe handles which are not a data member of a managed object. 00289 */ 00290 static Object& common(); 00291 00292 /** 00293 * Executable entrypoint for the System class. 00294 * 00295 * Print the Coherence library version information. 00296 */ 00297 static void main(ObjectArray::View); 00298 00299 00300 // ----- nested class: CommonMonitor ------------------------------------ 00301 00302 public: 00303 /** 00304 * A class which acts as CommonMonitor. 00305 * 00306 * The custom class is produced to aid in identification while profiling. 00307 */ 00308 class COH_EXPORT CommonMonitor 00309 : public class_spec<CommonMonitor> 00310 { 00311 friend class factory<CommonMonitor>; 00312 00313 protected: 00314 CommonMonitor() {} 00315 }; 00316 }; 00317 00318 COH_CLOSE_NAMESPACE2 00319 00320 #endif // COH_SYSTEM_HPP