| 1 | /* |
| 2 | Copyright (c) 2005-2019 Intel Corporation |
| 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 | #ifndef __TBB_shared_utils_H |
| 18 | #define __TBB_shared_utils_H |
| 19 | |
| 20 | // Include files containing declarations of intptr_t and uintptr_t |
| 21 | #include <stddef.h> // size_t |
| 22 | #if _MSC_VER |
| 23 | typedef unsigned __int16 uint16_t; |
| 24 | typedef unsigned __int32 uint32_t; |
| 25 | typedef unsigned __int64 uint64_t; |
| 26 | #if !UINTPTR_MAX |
| 27 | #define UINTPTR_MAX SIZE_MAX |
| 28 | #endif |
| 29 | #else // _MSC_VER |
| 30 | #include <stdint.h> |
| 31 | #endif |
| 32 | |
| 33 | /* |
| 34 | * Functions to align an integer down or up to the given power of two, |
| 35 | * and test for such an alignment, and for power of two. |
| 36 | */ |
| 37 | template<typename T> |
| 38 | static inline T alignDown(T arg, uintptr_t alignment) { |
| 39 | return T( (uintptr_t)arg & ~(alignment-1)); |
| 40 | } |
| 41 | template<typename T> |
| 42 | static inline T alignUp (T arg, uintptr_t alignment) { |
| 43 | return T(((uintptr_t)arg+(alignment-1)) & ~(alignment-1)); |
| 44 | // /*is this better?*/ return (((uintptr_t)arg-1) | (alignment-1)) + 1; |
| 45 | } |
| 46 | template<typename T> // works for not power-of-2 alignments |
| 47 | static inline T alignUpGeneric(T arg, uintptr_t alignment) { |
| 48 | if (size_t rem = arg % alignment) { |
| 49 | arg += alignment - rem; |
| 50 | } |
| 51 | return arg; |
| 52 | } |
| 53 | |
| 54 | template<typename T, size_t N> // generic function to find length of array |
| 55 | inline size_t arrayLength(const T(&)[N]) { |
| 56 | return N; |
| 57 | } |
| 58 | |
| 59 | /* |
| 60 | * Compile time Log2 calculation |
| 61 | */ |
| 62 | template <size_t NUM> |
| 63 | struct Log2 { static const int value = 1 + Log2<(NUM >> 1)>::value; }; |
| 64 | template <> |
| 65 | struct Log2<1> { static const int value = 0; }; |
| 66 | |
| 67 | #if defined(min) |
| 68 | #undef min |
| 69 | #endif |
| 70 | |
| 71 | template<typename T> |
| 72 | T min ( const T& val1, const T& val2 ) { |
| 73 | return val1 < val2 ? val1 : val2; |
| 74 | } |
| 75 | |
| 76 | /* |
| 77 | * Functions to parse files information (system files for example) |
| 78 | */ |
| 79 | |
| 80 | #include <stdio.h> |
| 81 | |
| 82 | #if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER) |
| 83 | // Suppress overzealous compiler warnings that default ctor and assignment |
| 84 | // operator cannot be generated and object 'class' can never be instantiated. |
| 85 | #pragma warning(push) |
| 86 | #pragma warning(disable:4510 4512 4610) |
| 87 | #endif |
| 88 | |
| 89 | #if __SUNPRO_CC |
| 90 | // Suppress overzealous compiler warnings that a class with a reference member |
| 91 | // lacks a user-defined constructor, which can lead to errors |
| 92 | #pragma error_messages (off, refmemnoconstr) |
| 93 | #endif |
| 94 | |
| 95 | // TODO: add a constructor to remove warnings suppression |
| 96 | struct parseFileItem { |
| 97 | const char* format; |
| 98 | unsigned long long& value; |
| 99 | }; |
| 100 | |
| 101 | #if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER) |
| 102 | #pragma warning(pop) |
| 103 | #endif |
| 104 | |
| 105 | #if __SUNPRO_CC |
| 106 | #pragma error_messages (on, refmemnoconstr) |
| 107 | #endif |
| 108 | |
| 109 | template <int BUF_LINE_SIZE, int N> |
| 110 | void parseFile(const char* file, const parseFileItem (&items)[N]) { |
| 111 | // Tries to find all items in each line |
| 112 | int found[N] = { 0 }; |
| 113 | // If all items found, stop forward file reading |
| 114 | int numFound = 0; |
| 115 | // Line storage |
| 116 | char buf[BUF_LINE_SIZE]; |
| 117 | |
| 118 | if (FILE *f = fopen(file, "r" )) { |
| 119 | while (numFound < N && fgets(buf, BUF_LINE_SIZE, f)) { |
| 120 | for (int i = 0; i < N; ++i) { |
| 121 | if (!found[i] && 1 == sscanf(buf, items[i].format, &items[i].value)) { |
| 122 | ++numFound; |
| 123 | found[i] = 1; |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | fclose(f); |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | namespace rml { |
| 132 | namespace internal { |
| 133 | |
| 134 | /* |
| 135 | * Best estimate of cache line size, for the purpose of avoiding false sharing. |
| 136 | * Too high causes memory overhead, too low causes false-sharing overhead. |
| 137 | * Because, e.g., 32-bit code might run on a 64-bit system with a larger cache line size, |
| 138 | * it would probably be better to probe at runtime where possible and/or allow for an environment variable override, |
| 139 | * but currently this is still used for compile-time layout of class Block, so the change is not entirely trivial. |
| 140 | */ |
| 141 | #if __powerpc64__ || __ppc64__ || __bgp__ |
| 142 | const uint32_t estimatedCacheLineSize = 128; |
| 143 | #else |
| 144 | const uint32_t estimatedCacheLineSize = 64; |
| 145 | #endif |
| 146 | |
| 147 | } // namespace internal |
| 148 | } // namespace rml |
| 149 | |
| 150 | #endif /* __TBB_shared_utils_H */ |
| 151 | |
| 152 | |