26#ifndef XTC_CORO_COMMON_H
27#define XTC_CORO_COMMON_H
44#define XTC_STACK_POOL_MAX 64
46 void *slots[XTC_STACK_POOL_MAX];
50static XTC_THREAD_LOCAL
struct stack_pool __stack_pool;
54__stack_pool_get(
size_t stack_sz)
57 if (p->n > 0 && p->size == stack_sz)
58 return p->slots[--p->n];
65__stack_pool_put(
void *base,
size_t stack_sz)
68 if (p->n == 0) p->size = stack_sz;
69 if (p->size != stack_sz || p->n == XTC_STACK_POOL_MAX)
71 p->slots[p->n++] = base;
82#if defined(MADV_DONTNEED)
83static _Atomic
int g_reclaim_on = 0;
84static _Atomic
size_t g_reclaim_keep = 0;
85static _Atomic uint64_t g_reclaim_count = 0;
88xtc_stack_reclaim_enable(
size_t keep_bytes)
90 long pg = sysconf(_SC_PAGESIZE);
91 size_t page = (pg > 0) ? (
size_t)pg : 4096u;
94 atomic_store(&g_reclaim_keep, keep_bytes);
95 atomic_store(&g_reclaim_on, 1);
100xtc_stack_reclaim_disable(
void)
102 atomic_store(&g_reclaim_on, 0);
106xtc_stack_reclaim_enabled(
void)
108 return atomic_load(&g_reclaim_on);
112xtc_stack_reclaim_count(
void)
114 return atomic_load(&g_reclaim_count);
127coro_stack_shrink(
struct xtc_coro *c,
void *sp)
131 uintptr_t lo, hi, guard, base;
133 if (c == NULL || c->stack == NULL || !atomic_load(&g_reclaim_on))
135 pgl = sysconf(_SC_PAGESIZE);
136 page = (pgl > 0) ? (
size_t)pgl : 4096u;
138 keep = atomic_load(&g_reclaim_keep);
140 base = (uintptr_t)c->stack + guard;
142 if (hi <= base + keep)
146 hi = (hi - keep) & ~(uintptr_t)(page - 1);
147 lo = (base + page - 1) & ~(uintptr_t)(page - 1);
148 if (hi <= lo || hi - lo < page)
150 if (madvise((
void *)lo, (size_t)(hi - lo), MADV_DONTNEED) == 0)
151 (void)atomic_fetch_add(&g_reclaim_count, 1);
154int xtc_stack_reclaim_enable(
size_t k) { (void)k;
return XTC_E_NOSYS; }
155void xtc_stack_reclaim_disable(
void) { }
156int xtc_stack_reclaim_enabled(
void) {
return 0; }
157uint64_t xtc_stack_reclaim_count(
void) {
return 0; }
158#define coro_stack_shrink(c, sp) ((void)(c), (void)(sp))