1 /*------------------------------------------------------------------------- 2 * 3 * freepage.h 4 * Management of page-organized free memory. 5 * 6 * Portions Copyright (c) 1996-2018, 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