xref: /oneTBB/src/tbbmalloc/shared_utils.h (revision e82d2503)
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