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 | |