xref: /src/contrib/jemalloc/include/jemalloc/internal/pai.h (revision c43cad87172039ccf38172129c79755ea79e6102)
1 #ifndef JEMALLOC_INTERNAL_PAI_H
2 #define JEMALLOC_INTERNAL_PAI_H
3 
4 /* An interface for page allocation. */
5 
6 typedef struct pai_s pai_t;
7 struct pai_s {
8 	/* Returns NULL on failure. */
9 	edata_t *(*alloc)(tsdn_t *tsdn, pai_t *self, size_t size,
10 	    size_t alignment, bool zero, bool guarded, bool frequent_reuse,
11 	    bool *deferred_work_generated);
12 	/*
13 	 * Returns the number of extents added to the list (which may be fewer
14 	 * than requested, in case of OOM).  The list should already be
15 	 * initialized.  The only alignment guarantee is page-alignment, and
16 	 * the results are not necessarily zeroed.
17 	 */
18 	size_t (*alloc_batch)(tsdn_t *tsdn, pai_t *self, size_t size,
19 	    size_t nallocs, edata_list_active_t *results,
20 	    bool *deferred_work_generated);
21 	bool (*expand)(tsdn_t *tsdn, pai_t *self, edata_t *edata,
22 	    size_t old_size, size_t new_size, bool zero,
23 	    bool *deferred_work_generated);
24 	bool (*shrink)(tsdn_t *tsdn, pai_t *self, edata_t *edata,
25 	    size_t old_size, size_t new_size, bool *deferred_work_generated);
26 	void (*dalloc)(tsdn_t *tsdn, pai_t *self, edata_t *edata,
27 	    bool *deferred_work_generated);
28 	/* This function empties out list as a side-effect of being called. */
29 	void (*dalloc_batch)(tsdn_t *tsdn, pai_t *self,
30 	    edata_list_active_t *list, bool *deferred_work_generated);
31 	uint64_t (*time_until_deferred_work)(tsdn_t *tsdn, pai_t *self);
32 };
33 
34 /*
35  * These are just simple convenience functions to avoid having to reference the
36  * same pai_t twice on every invocation.
37  */
38 
39 static inline edata_t *
pai_alloc(tsdn_t * tsdn,pai_t * self,size_t size,size_t alignment,bool zero,bool guarded,bool frequent_reuse,bool * deferred_work_generated)40 pai_alloc(tsdn_t *tsdn, pai_t *self, size_t size, size_t alignment,
41     bool zero, bool guarded, bool frequent_reuse,
42     bool *deferred_work_generated) {
43 	return self->alloc(tsdn, self, size, alignment, zero, guarded,
44 	    frequent_reuse, deferred_work_generated);
45 }
46 
47 static inline size_t
pai_alloc_batch(tsdn_t * tsdn,pai_t * self,size_t size,size_t nallocs,edata_list_active_t * results,bool * deferred_work_generated)48 pai_alloc_batch(tsdn_t *tsdn, pai_t *self, size_t size, size_t nallocs,
49     edata_list_active_t *results, bool *deferred_work_generated) {
50 	return self->alloc_batch(tsdn, self, size, nallocs, results,
51 	    deferred_work_generated);
52 }
53 
54 static inline bool
pai_expand(tsdn_t * tsdn,pai_t * self,edata_t * edata,size_t old_size,size_t new_size,bool zero,bool * deferred_work_generated)55 pai_expand(tsdn_t *tsdn, pai_t *self, edata_t *edata, size_t old_size,
56     size_t new_size, bool zero, bool *deferred_work_generated) {
57 	return self->expand(tsdn, self, edata, old_size, new_size, zero,
58 	    deferred_work_generated);
59 }
60 
61 static inline bool
pai_shrink(tsdn_t * tsdn,pai_t * self,edata_t * edata,size_t old_size,size_t new_size,bool * deferred_work_generated)62 pai_shrink(tsdn_t *tsdn, pai_t *self, edata_t *edata, size_t old_size,
63     size_t new_size, bool *deferred_work_generated) {
64 	return self->shrink(tsdn, self, edata, old_size, new_size,
65 	    deferred_work_generated);
66 }
67 
68 static inline void
pai_dalloc(tsdn_t * tsdn,pai_t * self,edata_t * edata,bool * deferred_work_generated)69 pai_dalloc(tsdn_t *tsdn, pai_t *self, edata_t *edata,
70     bool *deferred_work_generated) {
71 	self->dalloc(tsdn, self, edata, deferred_work_generated);
72 }
73 
74 static inline void
pai_dalloc_batch(tsdn_t * tsdn,pai_t * self,edata_list_active_t * list,bool * deferred_work_generated)75 pai_dalloc_batch(tsdn_t *tsdn, pai_t *self, edata_list_active_t *list,
76     bool *deferred_work_generated) {
77 	self->dalloc_batch(tsdn, self, list, deferred_work_generated);
78 }
79 
80 static inline uint64_t
pai_time_until_deferred_work(tsdn_t * tsdn,pai_t * self)81 pai_time_until_deferred_work(tsdn_t *tsdn, pai_t *self) {
82 	return self->time_until_deferred_work(tsdn, self);
83 }
84 
85 /*
86  * An implementation of batch allocation that simply calls alloc once for
87  * each item in the list.
88  */
89 size_t pai_alloc_batch_default(tsdn_t *tsdn, pai_t *self, size_t size,
90     size_t nallocs, edata_list_active_t *results, bool *deferred_work_generated);
91 /* Ditto, for dalloc. */
92 void pai_dalloc_batch_default(tsdn_t *tsdn, pai_t *self,
93     edata_list_active_t *list, bool *deferred_work_generated);
94 
95 #endif /* JEMALLOC_INTERNAL_PAI_H */
96