00001 /* 00002 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. 00003 * 00004 * Licensed under the Universal Permissive License v 1.0 as shown at 00005 * http://oss.oracle.com/licenses/upl. 00006 */ 00007 #ifndef COH_SYSTEM_HPP 00008 #define COH_SYSTEM_HPP 00009 00010 #include "coherence/lang/compatibility.hpp" 00011 00012 #include "coherence/lang/abstract_spec.hpp" 00013 #include "coherence/lang/HeapAnalyzer.hpp" 00014 #include "coherence/lang/ObjectArray.hpp" 00015 #include "coherence/lang/String.hpp" 00016 00017 #include <locale> 00018 00019 COH_OPEN_NAMESPACE2(coherence,lang) 00020 00021 00022 /** 00023 * A collection of general purpose utility methods. 00024 * 00025 * @author mf 2007.12.19 00026 */ 00027 class COH_EXPORT System 00028 : public abstract_spec<System> 00029 { 00030 // ----- constructors --------------------------------------------------- 00031 00032 private: 00033 /** 00034 * Blocked constructor. 00035 */ 00036 System(); 00037 00038 00039 // ----- System interface ----------------------------------------------- 00040 00041 public: 00042 /** 00043 * Runs the garbage collector. 00044 * 00045 * While most managed objects are automatically reclaimed when their 00046 * reference count reaches zero, some special case objects utilize 00047 * deferred automatic cleanup. Calling this method will expedite this 00048 * deferred cleanup. 00049 * 00050 * @param fFull true iff an exhaustive collection is desired 00051 */ 00052 static void gc(bool fFull = false); 00053 00054 /** 00055 * Return the number of milliseconds which have elapsed since the 00056 * process was started. 00057 * 00058 * @return the number of milliseconds which have elapsed since the 00059 * process was started 00060 */ 00061 static int64_t upTimeMillis(); 00062 00063 /** 00064 * Return the elapsed milliseconds since midnight January 1, 1970 UTC. 00065 * 00066 * This function does not guard against the clock rolling back or 00067 * jumping forward. 00068 * 00069 * @return the elapsed milliseconds 00070 */ 00071 static int64_t currentTimeMillis(); 00072 00073 /** 00074 * Returns a "safe" current time in milliseconds. 00075 * 00076 * Unlike the #currentTimeMillis() this method guarantees that the 00077 * time never "goes back". 00078 * 00079 * More specifically, when called twice on the same thread, the second 00080 * call will never return a value that is less then the value returned 00081 * by the first call. If a system time correction becomes necessary, an 00082 * attempt will be made to gradually compensate the returned value, so 00083 * in the long run the value returned by this method is the same as the 00084 * system time. 00085 * 00086 * Additionally, the following always holds true: 00087 * <pre> 00088 * System::safeTimeMillis() >= System::currentTimeMillis(); 00089 * </pre> 00090 * 00091 * @return the difference, measured in milliseconds, between 00092 * the corrected current time and midnight, January 1, 1970 UTC. 00093 */ 00094 static int64_t safeTimeMillis(); 00095 00096 /** 00097 * Returns the last "safe" time as computed by a previous call to 00098 * the {@link #safeTimeMillis} method. 00099 * 00100 * Note: Since the underlying field is non-volatile, the returned value 00101 * is only guaranteed to be no less than the last value returned by 00102 * safeTimeMillis() call on the same thread. 00103 * 00104 * @return the last "safe" time in milliseconds 00105 */ 00106 static int64_t lastSafeTimeMillis(); 00107 00108 /** 00109 * Return the value of a system property. 00110 * 00111 * The standard naming convention for system properties is '.' 00112 * Separated property names, such as "coherence.setting". 00113 * 00114 * As of Coherence 3.4 the only source for system properties is 00115 * environment variables. As some environments do not allow '.' in 00116 * variable names, a failed lookup will be automatically re-issued 00117 * using a camel-cased version of the supplied name, i.e. the property 00118 * name "coherence.setting" would translate to 00119 * "CoherenceSetting". From a code level perspective 00120 * camel-case does not need to be a consideration, it is only when 00121 * setting environment variables that it may be needed. 00122 * 00123 * As of Coherence 12.2.1, the Coherence system property pattern 00124 * begins with "coherence.". This method looks up system property 00125 * by the provided vsName format. If vsName starts with "coherence." and 00126 * the system property lookup fails to find a value, this method retries 00127 * lookup with leading "tangosol." for backwards compatibility support. 00128 * 00129 * If vsName starts with "tangosol.", 00130 * it follows pre Coherence 12.2.1 Coherence system property pattern. 00131 * If lookup of vsName following this pattern occurs, then 00132 * a failed lookup is retried following Coherence 12.2.1 system 00133 * property pattern, replacing leading "tangosol." with 00134 * "coherence." 00135 * 00136 * @param vsName the name of the property to return 00137 * @param vsDefault the default value for the property 00138 * 00139 * @return the corresponding property value, or the supplied default if 00140 * no value could be found 00141 */ 00142 static String::View getProperty(String::View vsName, 00143 String::View vsDefault = String::null_string); 00144 00145 /** 00146 * Set the system property to a value. 00147 * 00148 * @param vsName the system property name 00149 * @param vsValue the value of the system property 00150 * 00151 * @return previous value of system property 00152 * 00153 * @since Coherence 12.2.1 00154 */ 00155 static String::View setProperty(String::View vsName, String::View vsValue); 00156 00157 /** 00158 * Clear system property's value. 00159 * 00160 * @param vsName the system property name to remove its value 00161 * 00162 * @return previous value of system property 00163 * 00164 * @since Coherence 12.2.1 00165 */ 00166 static String::View clearProperty(String::View vsName); 00167 00168 /** 00169 * Return the same hash code for the given object as would be returned 00170 * by the default implementation provided in Object. In the case of 00171 * NULL zero is returned. 00172 * 00173 * @param v the object to hash 00174 * 00175 * @return the object's identity hash code. 00176 */ 00177 static size32_t identityHashCode(Object::View v); 00178 00179 /** 00180 * Specify the system interrupt resolution. 00181 * 00182 * The resolution at which a blocked thread will test if it has been 00183 * interrupted. Not all blocking states are guaranteed to utilize this 00184 * feature, but at a minimum Object::wait(), and Coherence based network 00185 * communications do respect this setting. 00186 * 00187 * Once in a blocking state the blocked call may not see updates to this 00188 * setting. If this setting is to be updated it is recommended that it 00189 * only occur once at application startup. 00190 * 00191 * Recommended values are between 100 and 1000 milliseconds, default is 00192 * 250 milliseconds. 00193 * 00194 * @param cMillis the new interrupt resolution 00195 * 00196 * @throws IllegalArgumentException if cMillis <= 0 00197 */ 00198 static void setInterruptResolution(int64_t cMillis); 00199 00200 /** 00201 * Return the interrupt resolution. 00202 * 00203 * @return the interrupt resolution. 00204 */ 00205 static int64_t getInterruptResolution(); 00206 00207 /** 00208 * Load the specified library. 00209 */ 00210 static void loadLibrary(String::View vsLibName); 00211 00212 /** 00213 * Set the global locale. 00214 * 00215 * @param vsLocale the name of the locale to use, or NULL for the classic locale 00216 * 00217 * @return the name of the former locale 00218 */ 00219 COH_INLINE static String::View setLocale(String::View vsLocale) 00220 { 00221 if (vsLocale == NULL) 00222 { 00223 vsLocale = "C"; // classic locale 00224 } 00225 00226 // pass through to coh internals in case is using a different standard library. 00227 // Note we only do this by name as passing a std::local object across the lib 00228 // boundary may not be safe if different standard libraries are used 00229 String::View vsOld = System::setLocaleInternal(vsLocale); 00230 00231 // we also set it on the std version used by the caller, since this is inlined 00232 // it will pick up the callers library even if different from the one used internally 00233 std::locale loc(vsLocale->getCString()); 00234 std::cin.imbue(loc); 00235 std::cout.imbue(loc); 00236 std::cerr.imbue(loc); 00237 std::clog.imbue(loc); 00238 std::wcin.imbue(loc); 00239 std::wcout.imbue(loc); 00240 std::wcerr.imbue(loc); 00241 std::wclog.imbue(loc); 00242 std::locale::global(loc); 00243 00244 return vsOld; 00245 } 00246 00247 // ----- diagnostics methods -------------------------------------------- 00248 00249 public: 00250 /** 00251 * Test that the attach count on the Object is the expected value. 00252 * 00253 * This method is for testing purposes only, and will throw an 00254 * exception if the count is not the expected value. 00255 * 00256 * @param v the Object to test 00257 * @param cHandle the expected number of handles attached to this 00258 * Object 00259 * @param fEscaped the expected object escape state 00260 */ 00261 static void assertAttachCount(Object::View v, uint32_t cHandle, 00262 uint32_t cView); 00263 00264 /** 00265 * Return a string representation of the Object's life-cycle state. 00266 * 00267 * This is intended for diagnostics purposes only. 00268 * 00269 * @param v the Object to describe 00270 * 00271 * @return a human-readable description of the object's life-cycle 00272 * state 00273 */ 00274 static String::View getLifeCycleDescription(Object::View v); 00275 00276 /** 00277 * Return the System HeapAnalyzer. 00278 * 00279 * There may be only one HeapAnalyzer for the life of the process, the 00280 * default being the ObjectCountHeapAnalyzer, which is very low cost. 00281 * 00282 * The HeapAnalyzer to use may be specified via the 00283 * "coherence.heap.analyzer" system property, can can be set 00284 * to either a registered class name, or to "none". 00285 * 00286 * If using a heap-analyzer other then the default, some Objects 00287 * created during static initialization may not be registered. 00288 * 00289 * @return the System HeapAnalyzer. 00290 */ 00291 static HeapAnalyzer::Handle getHeapAnalyzer(); 00292 00293 /** 00294 * Return the common monitor associated with the specified integer 00295 * value. 00296 * 00297 * Common monitors allow for a low-cost means to reduce contention by 00298 * spreading synchronization over a large number of monitors. An 00299 * example usage would be to produce an "atomic array". For instance 00300 * to atomically change an element within an array which is being 00301 * simultaneously updated by multiple threads: 00302 * <pre> 00303 * COH_SYNCHRONIZED (System::getCommonMonitor( 00304 * System::identityHashCode(aoShared) + i)) 00305 * { 00306 * oOld = haoShared[i]; 00307 * haoShared[i] = oNew; 00308 * } 00309 * </pre> 00310 * With this approach many threads may concurrently access various 00311 * array elements without having to synchronize on the array itself, 00312 * and contend with each other. The use of common monitors also avoids 00313 * the overhead of allocating a unique monitor per index. This example 00314 * additionally makes use of the array's identity hash code to avoid 00315 * frequent collisions against other atomic arrays for the same indices. 00316 * 00317 * As they are shared, these monitors will apply to any number of 00318 * unrelated entities, and as such certain precautions must be employed 00319 * when using them. 00320 * <ul> 00321 * <li>The holder of a common monitor MUST not synchronize on any other 00322 * common monitor. Failure to adhere to this precaution will result 00323 * in a deadlock. 00324 * <li>Notifications on a common monitor MUST use notifyAll() rather 00325 * then notify(), as there may be unrelated threads waiting for 00326 * notification on the same monitor which could consume a single 00327 * notification. Thus the only way to ensure that the desired 00328 * thread does receive notification is to notify all threads 00329 * waiting on the monitor. 00330 * <li>Threads waiting for a notification must protect themselves 00331 * against spurious style wakeups. While this is a general, though 00332 * often overlooked part of the normal use of notification, with 00333 * common monitors it is far more likely that a thread will be 00334 * notified due to an unrelated event. 00335 * <li>A thread which is holding synchronization on a common monitor 00336 * should avoid blocking operations as this could block unrelated 00337 * threads which happen to be utilizing the same common monitor. 00338 * </ul> 00339 * The ideal number of common monitors in a process is one per 00340 * concurrently executing thread. As this number is generally unknown 00341 * the default number of monitors set to a relatively high value. The 00342 * value may also be manually specified via the 00343 * <code>tangosol.coherence.commonmonitors</code> system property. 00344 * 00345 * @param i the common monitor identifier 00346 * 00347 * @return the associated monitor 00348 */ 00349 static Object::Handle getCommonMonitor(size32_t i); 00350 00351 /** 00352 * Return the common monitor associated with the specified long value. 00353 * 00354 * @param l the common monitor identifier 00355 * 00356 * @return the associated monitor 00357 * 00358 * @see #getCommonMonitor(size32_t) 00359 */ 00360 static Object::Handle getCommonMonitor(size64_t l); 00361 00362 /** 00363 * Return a random common monitor for use as the guardian of 00364 * thread-safe handles which are not a data member of a managed object. 00365 */ 00366 static Object& common(); 00367 00368 /** 00369 * Return true if common monitors have been initialized. 00370 */ 00371 static bool isCommonMonitorInitialized(); 00372 00373 /** 00374 * Executable entrypoint for the System class. 00375 * 00376 * Print the Coherence library version information. 00377 */ 00378 static void main(ObjectArray::View); 00379 00380 00381 // ----- helper methods ------------------------------------------------- 00382 00383 protected: 00384 /** 00385 * Internal helper for specifying the global locale used within 00386 * the Coherence library. 00387 */ 00388 static String::View setLocaleInternal(String::View vsLocale); 00389 00390 00391 // ----- nested class: CommonMonitor ------------------------------------ 00392 00393 public: 00394 /** 00395 * A class which acts as CommonMonitor. 00396 * 00397 * The custom class is produced to aid in identification while profiling. 00398 */ 00399 class COH_EXPORT CommonMonitor 00400 : public class_spec<CommonMonitor> 00401 { 00402 friend class factory<CommonMonitor>; 00403 00404 protected: 00405 CommonMonitor() {} 00406 }; 00407 }; 00408 00409 COH_CLOSE_NAMESPACE2 00410 00411 #endif // COH_SYSTEM_HPP