123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- /*-------------------------------------------------------------------------
- *
- * freepage.h
- * Management of page-organized free memory.
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/utils/freepage.h
- *
- *-------------------------------------------------------------------------
- */
- #ifndef FREEPAGE_H
- #define FREEPAGE_H
- #include "storage/lwlock.h"
- #include "utils/relptr.h"
- /* Forward declarations. */
- typedef struct FreePageSpanLeader FreePageSpanLeader;
- typedef struct FreePageBtree FreePageBtree;
- typedef struct FreePageManager FreePageManager;
- /*
- * PostgreSQL normally uses 8kB pages for most things, but many common
- * architecture/operating system pairings use a 4kB page size for memory
- * allocation, so we do that here also.
- */
- #define FPM_PAGE_SIZE 4096
- /*
- * Each freelist except for the last contains only spans of one particular
- * size. Everything larger goes on the last one. In some sense this seems
- * like a waste since most allocations are in a few common sizes, but it
- * means that small allocations can simply pop the head of the relevant list
- * without needing to worry about whether the object we find there is of
- * precisely the correct size (because we know it must be).
- */
- #define FPM_NUM_FREELISTS 129
- /* Define relative pointer types. */
- relptr_declare(FreePageBtree, RelptrFreePageBtree);
- relptr_declare(FreePageManager, RelptrFreePageManager);
- relptr_declare(FreePageSpanLeader, RelptrFreePageSpanLeader);
- /* Everything we need in order to manage free pages (see freepage.c) */
- struct FreePageManager
- {
- RelptrFreePageManager self;
- RelptrFreePageBtree btree_root;
- RelptrFreePageSpanLeader btree_recycle;
- unsigned btree_depth;
- unsigned btree_recycle_count;
- Size singleton_first_page;
- Size singleton_npages;
- Size contiguous_pages;
- bool contiguous_pages_dirty;
- RelptrFreePageSpanLeader freelist[FPM_NUM_FREELISTS];
- #ifdef FPM_EXTRA_ASSERTS
- /* For debugging only, pages put minus pages gotten. */
- Size free_pages;
- #endif
- };
- /* Macros to convert between page numbers (expressed as Size) and pointers. */
- #define fpm_page_to_pointer(base, page) \
- (AssertVariableIsOfTypeMacro(page, Size), \
- (base) + FPM_PAGE_SIZE * (page))
- #define fpm_pointer_to_page(base, ptr) \
- (((Size) (((char *) (ptr)) - (base))) / FPM_PAGE_SIZE)
- /* Macro to convert an allocation size to a number of pages. */
- #define fpm_size_to_pages(sz) \
- (((sz) + FPM_PAGE_SIZE - 1) / FPM_PAGE_SIZE)
- /* Macros to check alignment of absolute and relative pointers. */
- #define fpm_pointer_is_page_aligned(base, ptr) \
- (((Size) (((char *) (ptr)) - (base))) % FPM_PAGE_SIZE == 0)
- #define fpm_relptr_is_page_aligned(base, relptr) \
- (relptr_offset(relptr) % FPM_PAGE_SIZE == 0)
- /* Macro to find base address of the segment containing a FreePageManager. */
- #define fpm_segment_base(fpm) \
- (((char *) fpm) - relptr_offset(fpm->self))
- /* Macro to access a FreePageManager's largest consecutive run of pages. */
- #define fpm_largest(fpm) \
- (fpm->contiguous_pages)
- /* Functions to manipulate the free page map. */
- extern void FreePageManagerInitialize(FreePageManager *fpm, char *base);
- extern bool FreePageManagerGet(FreePageManager *fpm, Size npages,
- Size *first_page);
- extern void FreePageManagerPut(FreePageManager *fpm, Size first_page,
- Size npages);
- extern char *FreePageManagerDump(FreePageManager *fpm);
- #endif /* FREEPAGE_H */
|