codekingpro/portable-devtools
114k
1#ifndef Py_INTERNAL_FREELIST_H2#define Py_INTERNAL_FREELIST_H3#ifdef __cplusplus4extern "C" {5#endif6 7#ifndef Py_BUILD_CORE8# error "this header requires Py_BUILD_CORE define"9#endif10 11#include "pycore_freelist_state.h" // struct _Py_freelists12#include "pycore_interp_structs.h" // PyInterpreterState13#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED()14#include "pycore_pystate.h" // _PyThreadState_GET15#include "pycore_stats.h" // OBJECT_STAT_INC16 17static inline struct _Py_freelists *18_Py_freelists_GET(void)19{20 PyThreadState *tstate = _PyThreadState_GET();21#ifdef Py_DEBUG22 _Py_EnsureTstateNotNULL(tstate);23#endif24 25#ifdef Py_GIL_DISABLED26 return &((_PyThreadStateImpl*)tstate)->freelists;27#else28 return &tstate->interp->object_state.freelists;29#endif30}31 32// Pushes `op` to the freelist, calls `freefunc` if the freelist is full33#define _Py_FREELIST_FREE(NAME, op, freefunc) \34 _PyFreeList_Free(&_Py_freelists_GET()->NAME, _PyObject_CAST(op), \35 Py_ ## NAME ## _MAXFREELIST, freefunc)36// Pushes `op` to the freelist, returns 1 if successful, 0 if the freelist is full37#define _Py_FREELIST_PUSH(NAME, op, limit) \38 _PyFreeList_Push(&_Py_freelists_GET()->NAME, _PyObject_CAST(op), limit)39 40// Pops a PyObject from the freelist, returns NULL if the freelist is empty.41#define _Py_FREELIST_POP(TYPE, NAME) \42 _Py_CAST(TYPE*, _PyFreeList_Pop(&_Py_freelists_GET()->NAME))43 44// Pops a non-PyObject data structure from the freelist, returns NULL if the45// freelist is empty.46#define _Py_FREELIST_POP_MEM(NAME) \47 _PyFreeList_PopMem(&_Py_freelists_GET()->NAME)48 49#define _Py_FREELIST_SIZE(NAME) (int)((_Py_freelists_GET()->NAME).size)50 51static inline int52_PyFreeList_Push(struct _Py_freelist *fl, void *obj, Py_ssize_t maxsize)53{54 if (fl->size < maxsize && fl->size >= 0) {55 FT_ATOMIC_STORE_PTR_RELAXED(*(void **)obj, fl->freelist);56 fl->freelist = obj;57 fl->size++;58 OBJECT_STAT_INC(to_freelist);59 return 1;60 }61 return 0;62}63 64static inline void65_PyFreeList_Free(struct _Py_freelist *fl, void *obj, Py_ssize_t maxsize,66 freefunc dofree)67{68 if (!_PyFreeList_Push(fl, obj, maxsize)) {69 dofree(obj);70 }71}72 73static inline void *74_PyFreeList_PopNoStats(struct _Py_freelist *fl)75{76 void *obj = fl->freelist;77 if (obj != NULL) {78 assert(fl->size > 0);79 fl->freelist = *(void **)obj;80 fl->size--;81 }82 return obj;83}84 85static inline PyObject *86_PyFreeList_Pop(struct _Py_freelist *fl)87{88 PyObject *op = _PyFreeList_PopNoStats(fl);89 if (op != NULL) {90 OBJECT_STAT_INC(from_freelist);91 _Py_NewReference(op);92 }93 return op;94}95 96static inline void *97_PyFreeList_PopMem(struct _Py_freelist *fl)98{99 void *op = _PyFreeList_PopNoStats(fl);100 if (op != NULL) {101 OBJECT_STAT_INC(from_freelist);102 }103 return op;104}105 106extern void _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization);107 108#ifdef __cplusplus109}110#endif111#endif /* !Py_INTERNAL_FREELIST_H */112 