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
23typedef unsigned __int16 uint16_t;
24typedef unsigned __int32 uint32_t;
25typedef 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 */
37template<typename T>
38static inline T alignDown(T arg, uintptr_t alignment) {
39 return T( (uintptr_t)arg & ~(alignment-1));
40}
41template<typename T>
42static 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}
46template<typename T> // works for not power-of-2 alignments
47static 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
54template<typename T, size_t N> // generic function to find length of array
55inline size_t arrayLength(const T(&)[N]) {
56 return N;
57}
58
59/*
60 * Compile time Log2 calculation
61 */
62template <size_t NUM>
63struct Log2 { static const int value = 1 + Log2<(NUM >> 1)>::value; };
64template <>
65struct Log2<1> { static const int value = 0; };
66
67#if defined(min)
68#undef min
69#endif
70
71template<typename T>
72T 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
96struct 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
109template <int BUF_LINE_SIZE, int N>
110void 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
131namespace rml {
132namespace 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__
142const uint32_t estimatedCacheLineSize = 128;
143#else
144const uint32_t estimatedCacheLineSize = 64;
145#endif
146
147} // namespace internal
148} // namespace rml
149
150#endif /* __TBB_shared_utils_H */
151
152