block.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // Copyright © 2018-2019 Ariadne Devos
  3. #ifndef _sHT_BLOCK_H
  4. #define _sHT_BLOCK_H
  5. #include <stddef.h>
  6. #ifndef _WIN32
  7. # include <sys/mman.h>
  8. #endif
  9. /** Memory blocks
  10. A read-write byte region backed by physical memory, contiguously addressable
  11. from virtual memory. On their own, they do not have a particular layout or
  12. type.
  13. To be allocated efficiently, space and time-wise, they should be at
  14. the very least one page large (4KiB on x86). (However, within the kernel,
  15. it should usually be exactly a single page, see Linux
  16. Documentation/flexible-arrays.txt).
  17. Allocation can be done in batch using @var{sHT_block_alloc_batch} and
  18. @var{sHT_block_free_batch}, or one at a time with @var{sHT_block_alloc}
  19. and @var{sHT_block_free}.
  20. This API is effectively an abstraction with a specification around:
  21. Unix userspace: mmap(2) or malloc(3).
  22. W32: VirtualAlloc(2).
  23. Linux kernel: alloc_pages (requires little pages). */
  24. #ifndef _WIN32
  25. /** A special value indicating a memory allocation failure, returned
  26. by @var{sHT_block_alloc}. It is not necessarily @code{NULL}.
  27. TODO: this is NULL on W32
  28. (<https://msdn.microsoft.com/en-us/library/Aa366887(v=VS.85).aspx>). */
  29. #define sHT_BLOCK_ALLOC_FAILED (MAP_FAILED)
  30. #else
  31. #define sHT_BLOCK_ALLOC_FAILED (NULL)
  32. #endif
  33. /** A minimal alignment of a blocks address.
  34. The actual alignment may be higher. */
  35. #define sHT_BLOCK_ALIGN 4096
  36. /** Try to allocate a memory block
  37. @var{size}: a positive number, a minimum on the number of bytes of the block
  38. If the function call is cancelled (e.g. by pthread_cancel(3)) or jumped over
  39. and not restored (e.g. by longjmp(3) from a signal handler), a block of
  40. memory of @var{size} bytes or a bit more may be leaked within the process.
  41. On an out-of-memory condition, the despeculated return value is
  42. @var{sHT_BLOCK_ALLOC_FAILED}. Else, it is a fresh block that can be freed
  43. by @var{sHT_block_free}. */
  44. void *
  45. sHT_block_alloc(size_t size);
  46. /** Free a single memory block
  47. @var{block}: the block to free
  48. @var{size}: the size of the block
  49. On a speculative execution, the block might actually not be freed.
  50. If cancelled (e.g. by pthread_cancel(3)) or jumped over (e.g. by longjmp(3)
  51. from a signal handler), the block may or may not be freed, resulting in a
  52. memory leak within the process of at most @var{size} plus delta. */
  53. void
  54. sHT_block_free(void *block, size_t size);
  55. /** Try to allocate @var{n} memory blocks of particular sizes
  56. @var{n}: the length of @var{dest} and @var{sizes}
  57. @var{dest}: a list of block pointers to write. May not be accessed
  58. concurrently.
  59. @var{sizes}: a list of the positive sizes of each block to allocate, in the
  60. same order as @var{dest}. May not be modified.
  61. On a speculative execution, more or less blocks may actually be allocated
  62. and the return value may be incorrect. On a non-speculative execution,
  63. a return value of 1 indicates that the blocks could not be allocated as
  64. requested. Then there is no net change is memory consumption except for
  65. some change. 0 indicates all blocks were allocated.
  66. If cancelled (e.g. by pthread_cancel(3)) or jumped over (e.g. by longjmp(3)
  67. from a signal handler), there may be a memory leak within the process of at
  68. most the sum of @var{sizes} plus delta. */
  69. _Bool
  70. sHT_block_alloc_batch(size_t n, void *dest[], const size_t sizes[]);
  71. /** Free the memory blocks in @var{dest}
  72. @var{n}: the number of elements in @var{dest} and @var{sizes}
  73. @var{dest}: a readable list of distinct, allocated blocks to free.
  74. May not be accessed concurrently.
  75. @var{sizes}: a readable list of the size of each block of @var{dest},
  76. in the same order. May not be modified concurrently.
  77. Some elements of @var{dest} are freed. On a non-speculative execution,
  78. all are freed.
  79. If cancelled (e.g. by pthread_cancel(3)) or jumped over (e.g. by longjmp(3)
  80. from a signal handler), there may be a memory leak within the process of at
  81. most the sum of @var{sizes} plus delta.
  82. On a non-speculative execution, all are freed. Otherwise, it might only be
  83. a subset. */
  84. void
  85. sHT_block_free_batch(size_t n, void *const dest[], const size_t sizes[]);
  86. #endif