LCOV - code coverage report
Current view: top level - source/lib - alignment.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 4 4 100.0 %
Date: 2023-01-19 00:18:29 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /* Copyright (C) 2021 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : #ifndef INCLUDED_ALIGNMENT
      24             : #define INCLUDED_ALIGNMENT
      25             : 
      26             : #include "lib/sysdep/compiler.h"  // MSC_VERSION
      27             : #include "lib/sysdep/arch.h"  // ARCH_AMD64
      28             : 
      29             : template<typename T>
      30        5874 : inline bool IsAligned(T t, uintptr_t multiple)
      31             : {
      32        5874 :     return (uintptr_t(t) % multiple) == 0;
      33             : }
      34             : 
      35             : template<size_t multiple>
      36          46 : inline size_t Align(size_t n)
      37             : {
      38             :     cassert(multiple != 0 && ((multiple & (multiple-1)) == 0)); // is power of 2
      39          46 :     return (n + multiple-1) & ~(multiple-1);
      40             : }
      41             : 
      42             : 
      43             : // bridge the differences between MSC and GCC alignment definitions.
      44             : // example: ALIGNED(int, 8) myAlignedVariable = 0;
      45             : #if MSC_VERSION
      46             : # define ALIGNED(type, multiple) __declspec(align(multiple)) type
      47             : #elif GCC_VERSION
      48             : # define ALIGNED(type, multiple) type __attribute__((aligned(multiple)))
      49             : #else
      50             : # define ALIGNED(type, multiple) type
      51             : #endif
      52             : 
      53             : 
      54             : //
      55             : // SIMD vector
      56             : //
      57             : 
      58             : static const size_t vectorSize = 16;
      59             : #define VECTOR_ALIGNED(type) ALIGNED(type, 16)  // ALIGNED() requires a literal; keep in sync with vectorSize
      60             : 
      61             : #define ASSERT_VECTOR_MULTIPLE(size)\
      62             :     ASSERT(IsAligned(size, vectorSize))
      63             : 
      64             : #define ASSERT_VECTOR_ALIGNED(pointer)\
      65             :     ASSERT_VECTOR_MULTIPLE(pointer);\
      66             :     ASSUME_ALIGNED(pointer, vectorSize)
      67             : 
      68             : 
      69             : //
      70             : // CPU cache
      71             : //
      72             : 
      73             : static const size_t cacheLineSize = 64; // (L2)
      74             : #define CACHE_ALIGNED(type) ALIGNED(type, 64)   // ALIGNED() requires a literal; keep in sync with cacheLineSize
      75             : 
      76             : 
      77             : 
      78             : 
      79             : //
      80             : // MMU pages
      81             : //
      82             : 
      83             : #ifdef ARCH_PPC64
      84             : // NOTE: ppc64 can operate in either 4k or 64k page size mode
      85             : // If the define page size is larger than the active page size,
      86             : // the allocator functions normally.  If the defined page size
      87             : // is less than the active page size, the allocator fails tests.
      88             : //
      89             : // Define the page size to the maximum known architectural page
      90             : // size on ppc64 systems.
      91             : static const size_t g_PageSize = 64 * 1024; // 64 KB
      92             : #else
      93             : static const size_t g_PageSize = 4 * 1024;  // 4 KB
      94             : #endif
      95             : static const size_t g_LargePageSize = 2 * 1024 * 1024;  // 2 MB
      96             : 
      97             : 
      98             : //
      99             : // misc
     100             : //
     101             : 
     102             : static const size_t allocationAlignment = 16;
     103             : 
     104             : static const size_t KiB = size_t(1) << 10;
     105             : static const size_t MiB = size_t(1) << 20;
     106             : static const size_t GiB = size_t(1) << 30;
     107             : 
     108             : // waio opens files with FILE_FLAG_NO_BUFFERING, so Windows requires
     109             : // file offsets / buffers and sizes to be sector-aligned. querying the
     110             : // actual sector size via GetDiskFreeSpace is inconvenient and slow.
     111             : // we always request large blocks anyway, so just check whether inputs
     112             : // are aligned to a `maximum' sector size. this catches common mistakes
     113             : // before they cause scary "IO failed" errors. if the value turns out
     114             : // to be too low, the Windows APIs will still complain.
     115             : static const uintptr_t maxSectorSize = 0x1000;
     116             : 
     117             : #endif  // #ifndef INCLUDED_ALIGNMENT

Generated by: LCOV version 1.13