xref: /oneTBB/src/tbbmalloc/shared_utils.h (revision e82d2503)
1 /*
2     Copyright (c) 2005-2021 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>
alignDown(T arg,uintptr_t alignment)38 static inline T alignDown(T arg, uintptr_t alignment) {
39     return T( (uintptr_t)arg                & ~(alignment-1));
40 }
41 template<typename T>
alignUp(T arg,uintptr_t alignment)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
alignUpGeneric(T arg,uintptr_t alignment)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 /*
55  * Compile time Log2 calculation
56  */
57 template <size_t NUM>
58 struct Log2 { static const int value = 1 + Log2<(NUM >> 1)>::value; };
59 template <>
60 struct Log2<1> { static const int value = 0; };
61 
62 #if defined(min)
63 #undef min
64 #endif
65 
66 template<typename T>
67 T min ( const T& val1, const T& val2 ) {
68     return val1 < val2 ? val1 : val2;
69 }
70 
71 /*
72  * Functions to parse files information (system files for example)
73  */
74 
75 #include <stdio.h>
76 
77 #if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER)
78     // Suppress overzealous compiler warnings that default ctor and assignment
79     // operator cannot be generated and object 'class' can never be instantiated.
80     #pragma warning(push)
81     #pragma warning(disable:4510 4512 4610)
82 #endif
83 
84 #if __SUNPRO_CC
85     // Suppress overzealous compiler warnings that a class with a reference member
86     // lacks a user-defined constructor, which can lead to errors
87     #pragma error_messages (off, refmemnoconstr)
88 #endif
89 
90 // TODO: add a constructor to remove warnings suppression
91 struct parseFileItem {
92     const char* format;
93     long long& value;
94 };
95 
96 #if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER)
97     #pragma warning(pop)
98 #endif
99 
100 #if __SUNPRO_CC
101     #pragma error_messages (on, refmemnoconstr)
102 #endif
103 
104 template <int BUF_LINE_SIZE, int N>
105 void parseFile(const char* file, const parseFileItem (&items)[N]) {
106     // Tries to find all items in each line
107     int found[N] = { 0 };
108     // If all items found, stop forward file reading
109     int numFound = 0;
110     // Line storage
111     char buf[BUF_LINE_SIZE];
112 
113     if (FILE *f = fopen(file, "r")) {
114         while (numFound < N && fgets(buf, BUF_LINE_SIZE, f)) {
115             for (int i = 0; i < N; ++i) {
116                 if (!found[i] && 1 == sscanf(buf, items[i].format, &items[i].value)) {
117                     ++numFound;
118                     found[i] = 1;
119                 }
120             }
121         }
122         fclose(f);
123     }
124 }
125 
126 namespace rml {
127 namespace internal {
128 
129 /*
130  * Best estimate of cache line size, for the purpose of avoiding false sharing.
131  * Too high causes memory overhead, too low causes false-sharing overhead.
132  * Because, e.g., 32-bit code might run on a 64-bit system with a larger cache line size,
133  * it would probably be better to probe at runtime where possible and/or allow for an environment variable override,
134  * but currently this is still used for compile-time layout of class Block, so the change is not entirely trivial.
135  */
136 #if __powerpc64__ || __ppc64__ || __bgp__
137 const uint32_t estimatedCacheLineSize = 128;
138 #else
139 const uint32_t estimatedCacheLineSize =  64;
140 #endif
141 
142 } // namespace internal
143 } // namespace rml
144 
145 #endif /* __TBB_shared_utils_H */
146 
147