1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * freepage.h |
4 | * Management of page-organized free memory. |
5 | * |
6 | * Portions Copyright (c) 1996-2019, 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 | |
14 | #ifndef FREEPAGE_H |
15 | #define FREEPAGE_H |
16 | |
17 | #include "storage/lwlock.h" |
18 | #include "utils/relptr.h" |
19 | |
20 | /* Forward declarations. */ |
21 | typedef struct FreePageSpanLeader FreePageSpanLeader; |
22 | typedef struct FreePageBtree FreePageBtree; |
23 | typedef struct FreePageManager FreePageManager; |
24 | |
25 | /* |
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. |
29 | */ |
30 | #define FPM_PAGE_SIZE 4096 |
31 | |
32 | /* |
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). |
39 | */ |
40 | #define FPM_NUM_FREELISTS 129 |
41 | |
42 | /* Define relative pointer types. */ |
43 | relptr_declare(FreePageBtree, RelptrFreePageBtree); |
44 | relptr_declare(FreePageManager, RelptrFreePageManager); |
45 | relptr_declare(FreePageSpanLeader, RelptrFreePageSpanLeader); |
46 | |
47 | /* Everything we need in order to manage free pages (see freepage.c) */ |
48 | struct FreePageManager |
49 | { |
50 | RelptrFreePageManager self; |
51 | RelptrFreePageBtree btree_root; |
52 | RelptrFreePageSpanLeader btree_recycle; |
53 | unsigned btree_depth; |
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. */ |
62 | Size free_pages; |
63 | #endif |
64 | }; |
65 | |
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) |
72 | |
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) |
76 | |
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).relptr_off % FPM_PAGE_SIZE == 0) |
82 | |
83 | /* Macro to find base address of the segment containing a FreePageManager. */ |
84 | #define fpm_segment_base(fpm) \ |
85 | (((char *) fpm) - fpm->self.relptr_off) |
86 | |
87 | /* Macro to access a FreePageManager's largest consecutive run of pages. */ |
88 | #define fpm_largest(fpm) \ |
89 | (fpm->contiguous_pages) |
90 | |
91 | /* Functions to manipulate the free page map. */ |
92 | extern void FreePageManagerInitialize(FreePageManager *fpm, char *base); |
93 | extern bool FreePageManagerGet(FreePageManager *fpm, Size npages, |
94 | Size *first_page); |
95 | extern void FreePageManagerPut(FreePageManager *fpm, Size first_page, |
96 | Size npages); |
97 | extern char *FreePageManagerDump(FreePageManager *fpm); |
98 | |
99 | #endif /* FREEPAGE_H */ |
100 | |