151c0b2f7Stbbdev /*
2b15aabb3Stbbdev Copyright (c) 2005-2021 Intel Corporation
351c0b2f7Stbbdev
451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev you may not use this file except in compliance with the License.
651c0b2f7Stbbdev You may obtain a copy of the License at
751c0b2f7Stbbdev
851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev
1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev See the License for the specific language governing permissions and
1451c0b2f7Stbbdev limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev
1751c0b2f7Stbbdev #ifndef __TBB_shared_utils_H
1851c0b2f7Stbbdev #define __TBB_shared_utils_H
1951c0b2f7Stbbdev
2051c0b2f7Stbbdev // Include files containing declarations of intptr_t and uintptr_t
2151c0b2f7Stbbdev #include <stddef.h> // size_t
2251c0b2f7Stbbdev #if _MSC_VER
2351c0b2f7Stbbdev typedef unsigned __int16 uint16_t;
2451c0b2f7Stbbdev typedef unsigned __int32 uint32_t;
2551c0b2f7Stbbdev typedef unsigned __int64 uint64_t;
2651c0b2f7Stbbdev #if !UINTPTR_MAX
2751c0b2f7Stbbdev #define UINTPTR_MAX SIZE_MAX
2851c0b2f7Stbbdev #endif
2951c0b2f7Stbbdev #else // _MSC_VER
3051c0b2f7Stbbdev #include <stdint.h>
3151c0b2f7Stbbdev #endif
3251c0b2f7Stbbdev
3351c0b2f7Stbbdev /*
3451c0b2f7Stbbdev * Functions to align an integer down or up to the given power of two,
3551c0b2f7Stbbdev * and test for such an alignment, and for power of two.
3651c0b2f7Stbbdev */
3751c0b2f7Stbbdev template<typename T>
alignDown(T arg,uintptr_t alignment)3851c0b2f7Stbbdev static inline T alignDown(T arg, uintptr_t alignment) {
3951c0b2f7Stbbdev return T( (uintptr_t)arg & ~(alignment-1));
4051c0b2f7Stbbdev }
4151c0b2f7Stbbdev template<typename T>
alignUp(T arg,uintptr_t alignment)4251c0b2f7Stbbdev static inline T alignUp (T arg, uintptr_t alignment) {
4351c0b2f7Stbbdev return T(((uintptr_t)arg+(alignment-1)) & ~(alignment-1));
4451c0b2f7Stbbdev // /*is this better?*/ return (((uintptr_t)arg-1) | (alignment-1)) + 1;
4551c0b2f7Stbbdev }
4651c0b2f7Stbbdev template<typename T> // works for not power-of-2 alignments
alignUpGeneric(T arg,uintptr_t alignment)4751c0b2f7Stbbdev static inline T alignUpGeneric(T arg, uintptr_t alignment) {
4851c0b2f7Stbbdev if (size_t rem = arg % alignment) {
4951c0b2f7Stbbdev arg += alignment - rem;
5051c0b2f7Stbbdev }
5151c0b2f7Stbbdev return arg;
5251c0b2f7Stbbdev }
5351c0b2f7Stbbdev
5451c0b2f7Stbbdev /*
5551c0b2f7Stbbdev * Compile time Log2 calculation
5651c0b2f7Stbbdev */
5751c0b2f7Stbbdev template <size_t NUM>
5851c0b2f7Stbbdev struct Log2 { static const int value = 1 + Log2<(NUM >> 1)>::value; };
5951c0b2f7Stbbdev template <>
6051c0b2f7Stbbdev struct Log2<1> { static const int value = 0; };
6151c0b2f7Stbbdev
6251c0b2f7Stbbdev #if defined(min)
6351c0b2f7Stbbdev #undef min
6451c0b2f7Stbbdev #endif
6551c0b2f7Stbbdev
6651c0b2f7Stbbdev template<typename T>
6751c0b2f7Stbbdev T min ( const T& val1, const T& val2 ) {
6851c0b2f7Stbbdev return val1 < val2 ? val1 : val2;
6951c0b2f7Stbbdev }
7051c0b2f7Stbbdev
7151c0b2f7Stbbdev /*
7251c0b2f7Stbbdev * Functions to parse files information (system files for example)
7351c0b2f7Stbbdev */
7451c0b2f7Stbbdev
7551c0b2f7Stbbdev #include <stdio.h>
7651c0b2f7Stbbdev
7751c0b2f7Stbbdev #if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER)
7851c0b2f7Stbbdev // Suppress overzealous compiler warnings that default ctor and assignment
7951c0b2f7Stbbdev // operator cannot be generated and object 'class' can never be instantiated.
8051c0b2f7Stbbdev #pragma warning(push)
8151c0b2f7Stbbdev #pragma warning(disable:4510 4512 4610)
8251c0b2f7Stbbdev #endif
8351c0b2f7Stbbdev
8451c0b2f7Stbbdev #if __SUNPRO_CC
8551c0b2f7Stbbdev // Suppress overzealous compiler warnings that a class with a reference member
8651c0b2f7Stbbdev // lacks a user-defined constructor, which can lead to errors
8751c0b2f7Stbbdev #pragma error_messages (off, refmemnoconstr)
8851c0b2f7Stbbdev #endif
8951c0b2f7Stbbdev
9051c0b2f7Stbbdev // TODO: add a constructor to remove warnings suppression
9151c0b2f7Stbbdev struct parseFileItem {
9251c0b2f7Stbbdev const char* format;
93*e82d2503SIlya Isaev long long& value;
9451c0b2f7Stbbdev };
9551c0b2f7Stbbdev
9651c0b2f7Stbbdev #if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER)
9751c0b2f7Stbbdev #pragma warning(pop)
9851c0b2f7Stbbdev #endif
9951c0b2f7Stbbdev
10051c0b2f7Stbbdev #if __SUNPRO_CC
10151c0b2f7Stbbdev #pragma error_messages (on, refmemnoconstr)
10251c0b2f7Stbbdev #endif
10351c0b2f7Stbbdev
10451c0b2f7Stbbdev template <int BUF_LINE_SIZE, int N>
10551c0b2f7Stbbdev void parseFile(const char* file, const parseFileItem (&items)[N]) {
10651c0b2f7Stbbdev // Tries to find all items in each line
10751c0b2f7Stbbdev int found[N] = { 0 };
10851c0b2f7Stbbdev // If all items found, stop forward file reading
10951c0b2f7Stbbdev int numFound = 0;
11051c0b2f7Stbbdev // Line storage
11151c0b2f7Stbbdev char buf[BUF_LINE_SIZE];
11251c0b2f7Stbbdev
11351c0b2f7Stbbdev if (FILE *f = fopen(file, "r")) {
11451c0b2f7Stbbdev while (numFound < N && fgets(buf, BUF_LINE_SIZE, f)) {
11551c0b2f7Stbbdev for (int i = 0; i < N; ++i) {
11651c0b2f7Stbbdev if (!found[i] && 1 == sscanf(buf, items[i].format, &items[i].value)) {
11751c0b2f7Stbbdev ++numFound;
11851c0b2f7Stbbdev found[i] = 1;
11951c0b2f7Stbbdev }
12051c0b2f7Stbbdev }
12151c0b2f7Stbbdev }
12251c0b2f7Stbbdev fclose(f);
12351c0b2f7Stbbdev }
12451c0b2f7Stbbdev }
12551c0b2f7Stbbdev
12651c0b2f7Stbbdev namespace rml {
12751c0b2f7Stbbdev namespace internal {
12851c0b2f7Stbbdev
12951c0b2f7Stbbdev /*
13051c0b2f7Stbbdev * Best estimate of cache line size, for the purpose of avoiding false sharing.
13151c0b2f7Stbbdev * Too high causes memory overhead, too low causes false-sharing overhead.
13251c0b2f7Stbbdev * Because, e.g., 32-bit code might run on a 64-bit system with a larger cache line size,
13351c0b2f7Stbbdev * it would probably be better to probe at runtime where possible and/or allow for an environment variable override,
13451c0b2f7Stbbdev * but currently this is still used for compile-time layout of class Block, so the change is not entirely trivial.
13551c0b2f7Stbbdev */
13651c0b2f7Stbbdev #if __powerpc64__ || __ppc64__ || __bgp__
13751c0b2f7Stbbdev const uint32_t estimatedCacheLineSize = 128;
13851c0b2f7Stbbdev #else
13951c0b2f7Stbbdev const uint32_t estimatedCacheLineSize = 64;
14051c0b2f7Stbbdev #endif
14151c0b2f7Stbbdev
14251c0b2f7Stbbdev } // namespace internal
14351c0b2f7Stbbdev } // namespace rml
14451c0b2f7Stbbdev
14551c0b2f7Stbbdev #endif /* __TBB_shared_utils_H */
14651c0b2f7Stbbdev
147