/* Macros for gcc attributes */
#define NORET __attribute__((noreturn))
+#define USE_RESULT __atribute__((warn_unused_result))
#define UNUSED __attribute__((unused))
#define PACKED __attribute__((packed))
- #define NONNULL(...) __attribute__((nonnull((__VA_ARGS__))))
+ #define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
+ #define ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__)))
+#define CLEANUP(fun) __attribute__((cleanup(fun)))
#define STATIC_ASSERT(EXP) _Static_assert(EXP, #EXP)
#define STATIC_ASSERT_MSG(EXP,MSG) _Static_assert(EXP, MSG)
void *ralloc(pool *, struct resclass *);
+pool *rp_new(pool *, struct domain_generic *, const char *); /* Create a new pool */
+pool *rp_newf(pool *, struct domain_generic *, const char *, ...); /* Create a new pool with a formatted string as its name */
+pool *rp_vnewf(pool *, struct domain_generic *, const char *, va_list); /* Create a new pool with a formatted string as its name */
+void rp_free(pool *p); /* Free the whole pool */
+
extern pool root_pool;
+static inline pool *resource_parent(resource *r)
+{ return SKIP_BACK(pool, inside, resource_enlisted(r)); }
+
/* Normal memory blocks */
- void *mb_alloc(pool *, unsigned size);
- void *mb_allocz(pool *, unsigned size);
- void *mb_realloc(void *m, unsigned size);
+ void *mb_alloc(pool *, unsigned size) ALLOC_SIZE(2);
+ void *mb_allocz(pool *, unsigned size) ALLOC_SIZE(2);
+ void *mb_realloc(void *m, unsigned size) ALLOC_SIZE(2);
void mb_free(void *);
/* Memory pools with linear allocation */
} lp_state;
linpool *lp_new(pool *);
- void *lp_alloc(linpool *, unsigned size); /* Aligned */
- void *lp_allocu(linpool *, unsigned size); /* Unaligned */
- void *lp_allocz(linpool *, unsigned size); /* With clear */
+ void *lp_alloc(linpool *, unsigned size) ALLOC_SIZE(2); /* Aligned */
+ void *lp_allocu(linpool *, unsigned size) ALLOC_SIZE(2); /* Unaligned */
+ void *lp_allocz(linpool *, unsigned size) ALLOC_SIZE(2); /* With clear */
void lp_flush(linpool *); /* Free everything, but leave linpool */
-void lp_save(linpool *m, lp_state *p); /* Save state */
+lp_state *lp_save(linpool *m); /* Save state */
void lp_restore(linpool *m, lp_state *p); /* Restore state */
-extern _Thread_local linpool *tmp_linpool; /* Temporary linpool autoflushed regularily */
+static inline void lp_saved_cleanup(struct lp_state **lps)
+{
+ if (*lps)
+ lp_restore((*lps)->p, (*lps));
+}
+#define LP_SAVED(m) for (CLEANUP(lp_saved_cleanup) struct lp_state *_lp_state = lp_save(m); _lp_state; lp_restore(m, _lp_state), _lp_state = NULL)
+
+#define lp_new_default lp_new
+
+/* Thread-local temporary linpools */
+
+extern _Thread_local linpool *tmp_linpool;
#define tmp_alloc(sz) lp_alloc(tmp_linpool, sz)
#define tmp_allocu(sz) lp_allocu(tmp_linpool, sz)
#define tmp_allocz(sz) lp_allocz(tmp_linpool, sz)