1 // ============================================================================= 2 // PROJECT CHRONO - http://projectchrono.org 3 // 4 // Copyright (c) 2014 projectchrono.org 5 // All rights reserved. 6 // 7 // Use of this source code is governed by a BSD-style license that can be found 8 // in the LICENSE file at the top level of the distribution and at 9 // http://projectchrono.org/license-chrono.txt. 10 // 11 // ============================================================================= 12 13 #include <cstring> 14 15 #include "chrono/core/ChGlobal.h" 16 17 #include "chrono_thirdparty/filesystem/path.h" 18 19 #if defined(_WIN32) || defined(_WIN64) 20 #include "Windows.h" 21 #endif 22 23 #if defined(__APPLE__) 24 #include <libkern/OSAtomic.h> 25 #endif 26 27 namespace chrono { 28 29 // ----------------------------------------------------------------------------- 30 // Functions for assigning unique identifiers 31 // ----------------------------------------------------------------------------- 32 33 // Set the start value for the sequence of IDs (ATTENTION: not thread safe) 34 // Subsequent calls to GetUniqueIntID() will return val+1, val+2, etc. 35 static volatile int first_id = 100000; 36 SetFirstIntID(int val)37void SetFirstIntID(int val) { 38 first_id = val; 39 } 40 41 // Obtain a unique identifier (thread-safe; platform-dependent) 42 #if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__EMSCRIPTEN__)) 43 GetUniqueIntID()44int GetUniqueIntID() { 45 static volatile int id = first_id; 46 return __sync_add_and_fetch(&id, 1); 47 } 48 49 #elif defined(_WIN32) 50 GetUniqueIntID()51int GetUniqueIntID() { 52 volatile static long id = first_id; 53 return (int)InterlockedIncrement(&id); 54 } 55 56 #elif defined(_WIN64) 57 GetUniqueIntID()58int GetUniqueIntID() { 59 volatile static long long id = first_id; 60 return (int)InterlockedIncrement64(&id); 61 } 62 63 #elif defined(__APPLE__) 64 GetUniqueIntID()65int GetUniqueIntID() { 66 static volatile int32_t id = first_id; 67 return (int)OSAtomicIncrement32Barrier(&id); 68 } 69 70 #else 71 72 //// TODO 73 #error "No support for atomic operations on current platform!" 74 75 #endif 76 77 // ----------------------------------------------------------------------------- 78 // Functions for manipulating the Chrono data directory 79 // ----------------------------------------------------------------------------- 80 81 static std::string chrono_data_path("../data/"); 82 83 // Set the path to the Chrono data directory (ATTENTION: not thread safe) SetChronoDataPath(const std::string & path)84void SetChronoDataPath(const std::string& path) { 85 chrono_data_path = path; 86 } 87 88 // Obtain the current path to the Chrono data directory (thread safe) GetChronoDataPath()89const std::string& GetChronoDataPath() { 90 return chrono_data_path; 91 } 92 93 // Obtain the complete path to the specified filename, given relative to the 94 // Chrono data directory (thread safe) GetChronoDataFile(const std::string & filename)95std::string GetChronoDataFile(const std::string& filename) { 96 return chrono_data_path + filename; 97 } 98 99 // ----------------------------------------------------------------------------- 100 // Functions for manipulating the Chrono data directory 101 // ----------------------------------------------------------------------------- 102 103 static std::string chrono_out_path("DEMO_OUTPUT/"); 104 105 // Set the path to the Chrono output directory (ATTENTION: not thread safe) SetChronoOutputPath(const std::string & path)106void SetChronoOutputPath(const std::string& path) { 107 chrono_out_path = path; 108 } 109 GetChronoOutputPath()110const std::string& GetChronoOutputPath() { 111 // If the directory does not yet exists, create it. 112 auto out_path = filesystem::path(chrono_out_path); 113 if (!out_path.exists()) 114 filesystem::create_directory(out_path); 115 116 return chrono_out_path; 117 } 118 119 } // end namespace chrono 120