/* * (c) Copyright, Real-Time Innovations, 2002-2024. * All rights reserved. * * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef osapi_alignment_h #define osapi_alignment_h #include "osapi/osapi_dll.h" #include "osapi/osapi_type.h" #ifdef __cplusplus extern "C" { #endif /** @internal \file * \brief Memory alignment utility functions */ /** @internal \defgroup RTIOsapiAlignmentClass RTIOsapiAlignment * \ingroup RTIOsapiModule * \brief Helps with architecture-specific alignment * * Note that alignment is necessary for the following reasons: *
    *
  1. Required alignment for certain datatypes: on certain architectures * if certain types are not aligned correctly, there will be a bus- * error; this is fatal. * Typically the required alignment is 4 (int), 8 (double or * void* on 64-bit architectures) *
  2. Suggested alignment for certain types: on certain architectures, * using data-types that are not properly aligned will lead to a * large drop in performance (because e.g. several bus-accesses are * needed) *
  3. Compilers/architectures will pack and align C-structures in a way * that solves problems 1 and 2 for all C-structures. The alignment * is reflected in the behaviour of malloc()/calloc() and sizeof(). * The precise behaviour is complicated by the fact that many compilers * can be coaxed into non-default behaviour through command-line * options or instructions in the source (e.g. #pragma pack). * The code in this module will only function correctly if all source * is compiled with the same alignment; all bets are off in other * cases. *
  4. For certain applications, it makes sense to further align data * to achieve better performance. Common use cases are: * *
*/ /** @internal \ingroup RTIOsapiAlignmentClass @brief The RTIOsapiAlignment is the alignment in bytes; an address is aligned when is a positive integer multiple of the alignment */ typedef int RTIOsapiAlignment; /** @internal \ingroup RTIOsapiAlignmentClass * @brief Certain methods allow a default alignment: this should * be an alignment that follows the "malloc" alignment of * the architecture (aligned sufficiently to store any C-structure * efficiently). */ #define RTI_OSAPI_ALIGNMENT_DEFAULT (-1) /** @internal \ingroup RTIOsapiAlignmentClass * \brief Certain methods that return an alignment * can indicate an error in this way. */ #define RTI_OSAPI_ALIGNMENT_ERROR (0) /** @internal \ingroup RTIOsapiAlignmentClass * @brief static method to get alignment that is sufficient to store * a C-structure of ANY size: any C-structure in the architecture * can start on a boundary that is a multiple of * RTIOsapiAlignment_getDefaultAlignment(). * * @return the returned alignment is > 0, power of 2 */ extern RTIOsapiDllExport RTIOsapiAlignment RTIOsapiAlignment_getDefaultAlignment(void); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief static method to get the first address >= location that has * the given alignment. * * @param location \b In. Address * @param alignment \b In. must be > 0 and a power of 2 * @return An address >= location with the specified alignment */ extern RTIOsapiDllExport void *RTIOsapiAlignment_alignAddressUp( void *location, RTIOsapiAlignment alignment); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief method to round a size up to the next alignment boundary (passed as * a parameter). * * @param size \b In. Size * @param alignment \b In. must be > 0 * @return A size >= initial size with the specified alignment */ extern RTIOsapiDllExport size_t RTIOsapiAlignment_alignSizeUp(size_t size, RTIOsapiAlignment alignment); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief method to round an RTI_INT32 up to the next alignment boundary (passed * as a parameter). * * @param size \b In. Size * @param alignment \b In. must be > 0 * @return A size >= initial size with the specified alignment */ extern RTIOsapiDllExport RTI_INT32 RTIOsapiAlignment_alignInt32Up(RTI_INT32 size, RTIOsapiAlignment alignment); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief method to round an RTI_UINT32 up to the next alignment boundary * (passed as a parameter). * * @param size \b In. Size * @param alignment \b In. must be > 0 * @return A size >= initial size with the specified alignment */ extern RTIOsapiDllExport RTI_UINT32 RTIOsapiAlignment_alignUInt32Up(RTI_UINT32 size, RTIOsapiAlignment alignment); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief method to round an RTI_INT64 up to the next alignment boundary (passed * as a parameter). * * @param size \b In. Size * @param alignment \b In. must be > 0 * @return A size >= initial size with the specified alignment */ extern RTIOsapiDllExport RTI_INT64 RTIOsapiAlignment_alignInt64Up(RTI_INT64 size, RTIOsapiAlignment alignment); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief method to round an RTI_UINT64 up to the next alignment boundary * (passed as a parameter). * * @param size \b In. Size * @param alignment \b In. must be > 0 * @return A size >= initial size with the specified alignment */ extern RTIOsapiDllExport RTI_UINT64 RTIOsapiAlignment_alignUInt64Up(RTI_UINT64 size, RTIOsapiAlignment alignment); /** @internal * \ingroup RTIOsapiAlignmentClass * @brief method to test if a memory address is aligned * * @param size \b In. Size * @param alignment \b In. must be > 0 * @return A size >= initial size with the specified alignment */ extern RTIOsapiDllExport int RTIOsapiAlignment_isAligned( void *location, RTIOsapiAlignment alignment); #ifdef __cplusplus } /* extern "C" */ #endif #include "osapi/osapi_alignment_impl.h" #endif /* osapi_alignment_h */