2
0

dsa.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*-------------------------------------------------------------------------
  2. *
  3. * dsa.h
  4. * Dynamic shared memory areas.
  5. *
  6. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. *
  9. * IDENTIFICATION
  10. * src/include/utils/dsa.h
  11. *
  12. *-------------------------------------------------------------------------
  13. */
  14. #ifndef DSA_H
  15. #define DSA_H
  16. #include "port/atomics.h"
  17. #include "storage/dsm.h"
  18. /* The opaque type used for an area. */
  19. struct dsa_area;
  20. typedef struct dsa_area dsa_area;
  21. /*
  22. * If this system only uses a 32-bit value for size_t, then use the 32-bit
  23. * implementation of DSA. This limits the amount of DSA that can be created
  24. * to something significantly less than the entire 4GB address space because
  25. * the DSA pointer must encode both a segment identifier and an offset, but
  26. * that shouldn't be a significant limitation in practice.
  27. *
  28. * If this system doesn't support atomic operations on 64-bit values, then
  29. * we fall back to 32-bit dsa_pointer for lack of other options.
  30. *
  31. * For testing purposes, USE_SMALL_DSA_POINTER can be defined to force the use
  32. * of 32-bit dsa_pointer even on systems capable of supporting a 64-bit
  33. * dsa_pointer.
  34. */
  35. #if SIZEOF_SIZE_T == 4 || !defined(PG_HAVE_ATOMIC_U64_SUPPORT) || \
  36. defined(USE_SMALL_DSA_POINTER)
  37. #define SIZEOF_DSA_POINTER 4
  38. #else
  39. #define SIZEOF_DSA_POINTER 8
  40. #endif
  41. /*
  42. * The type of 'relative pointers' to memory allocated by a dynamic shared
  43. * area. dsa_pointer values can be shared with other processes, but must be
  44. * converted to backend-local pointers before they can be dereferenced. See
  45. * dsa_get_address. Also, an atomic version and appropriately sized atomic
  46. * operations.
  47. */
  48. #if SIZEOF_DSA_POINTER == 4
  49. typedef uint32 dsa_pointer;
  50. typedef pg_atomic_uint32 dsa_pointer_atomic;
  51. #define dsa_pointer_atomic_init pg_atomic_init_u32
  52. #define dsa_pointer_atomic_read pg_atomic_read_u32
  53. #define dsa_pointer_atomic_write pg_atomic_write_u32
  54. #define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u32
  55. #define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u32
  56. #define DSA_POINTER_FORMAT "%08x"
  57. #else
  58. typedef uint64 dsa_pointer;
  59. typedef pg_atomic_uint64 dsa_pointer_atomic;
  60. #define dsa_pointer_atomic_init pg_atomic_init_u64
  61. #define dsa_pointer_atomic_read pg_atomic_read_u64
  62. #define dsa_pointer_atomic_write pg_atomic_write_u64
  63. #define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u64
  64. #define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u64
  65. #define DSA_POINTER_FORMAT "%016" INT64_MODIFIER "x"
  66. #endif
  67. /* Flags for dsa_allocate_extended. */
  68. #define DSA_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) */
  69. #define DSA_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */
  70. #define DSA_ALLOC_ZERO 0x04 /* zero allocated memory */
  71. /* A sentinel value for dsa_pointer used to indicate failure to allocate. */
  72. #define InvalidDsaPointer ((dsa_pointer) 0)
  73. /* Check if a dsa_pointer value is valid. */
  74. #define DsaPointerIsValid(x) ((x) != InvalidDsaPointer)
  75. /* Allocate uninitialized memory with error on out-of-memory. */
  76. #define dsa_allocate(area, size) \
  77. dsa_allocate_extended(area, size, 0)
  78. /* Allocate zero-initialized memory with error on out-of-memory. */
  79. #define dsa_allocate0(area, size) \
  80. dsa_allocate_extended(area, size, DSA_ALLOC_ZERO)
  81. /*
  82. * The type used for dsa_area handles. dsa_handle values can be shared with
  83. * other processes, so that they can attach to them. This provides a way to
  84. * share allocated storage with other processes.
  85. *
  86. * The handle for a dsa_area is currently implemented as the dsm_handle
  87. * for the first DSM segment backing this dynamic storage area, but client
  88. * code shouldn't assume that is true.
  89. */
  90. typedef dsm_handle dsa_handle;
  91. extern dsa_area *dsa_create(int tranche_id);
  92. extern dsa_area *dsa_create_in_place(void *place, size_t size,
  93. int tranche_id, dsm_segment *segment);
  94. extern dsa_area *dsa_attach(dsa_handle handle);
  95. extern dsa_area *dsa_attach_in_place(void *place, dsm_segment *segment);
  96. extern void dsa_release_in_place(void *place);
  97. extern void dsa_on_dsm_detach_release_in_place(dsm_segment *, Datum);
  98. extern void dsa_on_shmem_exit_release_in_place(int, Datum);
  99. extern void dsa_pin_mapping(dsa_area *area);
  100. extern void dsa_detach(dsa_area *area);
  101. extern void dsa_pin(dsa_area *area);
  102. extern void dsa_unpin(dsa_area *area);
  103. extern void dsa_set_size_limit(dsa_area *area, size_t limit);
  104. extern size_t dsa_minimum_size(void);
  105. extern dsa_handle dsa_get_handle(dsa_area *area);
  106. extern dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags);
  107. extern void dsa_free(dsa_area *area, dsa_pointer dp);
  108. extern void *dsa_get_address(dsa_area *area, dsa_pointer dp);
  109. extern void dsa_trim(dsa_area *area);
  110. extern void dsa_dump(dsa_area *area);
  111. #endif /* DSA_H */