freepage.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*-------------------------------------------------------------------------
  2. *
  3. * freepage.h
  4. * Management of page-organized free memory.
  5. *
  6. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. *
  9. * src/include/utils/freepage.h
  10. *
  11. *-------------------------------------------------------------------------
  12. */
  13. #ifndef FREEPAGE_H
  14. #define FREEPAGE_H
  15. #include "storage/lwlock.h"
  16. #include "utils/relptr.h"
  17. /* Forward declarations. */
  18. typedef struct FreePageSpanLeader FreePageSpanLeader;
  19. typedef struct FreePageBtree FreePageBtree;
  20. typedef struct FreePageManager FreePageManager;
  21. /*
  22. * PostgreSQL normally uses 8kB pages for most things, but many common
  23. * architecture/operating system pairings use a 4kB page size for memory
  24. * allocation, so we do that here also.
  25. */
  26. #define FPM_PAGE_SIZE 4096
  27. /*
  28. * Each freelist except for the last contains only spans of one particular
  29. * size. Everything larger goes on the last one. In some sense this seems
  30. * like a waste since most allocations are in a few common sizes, but it
  31. * means that small allocations can simply pop the head of the relevant list
  32. * without needing to worry about whether the object we find there is of
  33. * precisely the correct size (because we know it must be).
  34. */
  35. #define FPM_NUM_FREELISTS 129
  36. /* Define relative pointer types. */
  37. relptr_declare(FreePageBtree, RelptrFreePageBtree);
  38. relptr_declare(FreePageManager, RelptrFreePageManager);
  39. relptr_declare(FreePageSpanLeader, RelptrFreePageSpanLeader);
  40. /* Everything we need in order to manage free pages (see freepage.c) */
  41. struct FreePageManager
  42. {
  43. RelptrFreePageManager self;
  44. RelptrFreePageBtree btree_root;
  45. RelptrFreePageSpanLeader btree_recycle;
  46. unsigned btree_depth;
  47. unsigned btree_recycle_count;
  48. Size singleton_first_page;
  49. Size singleton_npages;
  50. Size contiguous_pages;
  51. bool contiguous_pages_dirty;
  52. RelptrFreePageSpanLeader freelist[FPM_NUM_FREELISTS];
  53. #ifdef FPM_EXTRA_ASSERTS
  54. /* For debugging only, pages put minus pages gotten. */
  55. Size free_pages;
  56. #endif
  57. };
  58. /* Macros to convert between page numbers (expressed as Size) and pointers. */
  59. #define fpm_page_to_pointer(base, page) \
  60. (AssertVariableIsOfTypeMacro(page, Size), \
  61. (base) + FPM_PAGE_SIZE * (page))
  62. #define fpm_pointer_to_page(base, ptr) \
  63. (((Size) (((char *) (ptr)) - (base))) / FPM_PAGE_SIZE)
  64. /* Macro to convert an allocation size to a number of pages. */
  65. #define fpm_size_to_pages(sz) \
  66. (((sz) + FPM_PAGE_SIZE - 1) / FPM_PAGE_SIZE)
  67. /* Macros to check alignment of absolute and relative pointers. */
  68. #define fpm_pointer_is_page_aligned(base, ptr) \
  69. (((Size) (((char *) (ptr)) - (base))) % FPM_PAGE_SIZE == 0)
  70. #define fpm_relptr_is_page_aligned(base, relptr) \
  71. (relptr_offset(relptr) % FPM_PAGE_SIZE == 0)
  72. /* Macro to find base address of the segment containing a FreePageManager. */
  73. #define fpm_segment_base(fpm) \
  74. (((char *) fpm) - relptr_offset(fpm->self))
  75. /* Macro to access a FreePageManager's largest consecutive run of pages. */
  76. #define fpm_largest(fpm) \
  77. (fpm->contiguous_pages)
  78. /* Functions to manipulate the free page map. */
  79. extern void FreePageManagerInitialize(FreePageManager *fpm, char *base);
  80. extern bool FreePageManagerGet(FreePageManager *fpm, Size npages,
  81. Size *first_page);
  82. extern void FreePageManagerPut(FreePageManager *fpm, Size first_page,
  83. Size npages);
  84. extern char *FreePageManagerDump(FreePageManager *fpm);
  85. #endif /* FREEPAGE_H */