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