# pool.ludic - a message's record and its bytes are kept, never made again: a party sends and takes # dozens a second for as long as it plays, and Ludic frees nothing. A queued one goes back when it is # taken or goes stale; an inbox one comes back two drains after it was handed out function net__msg_take(net_st: mut NetState) -> NetMsg { if len(net_st.net__free) > 0 { return List.pop(net_st.net__free) } return net__msg_new() } # everything a peer had queued, back to the pool (its slot opened again, or let go) function net__queue_free(net_st: mut NetState, p: NetPeer) -> void { for i in 0 .. len(p.queue) { kept_push(net_st.net__free, p.queue[i]) } List.clear(p.queue) } # the halves swap whenever a message finds the inbox empty (everything before it drained or # cleared), so a reader of the last drain's list never sees one change function net__in_take(net_st: mut NetState) -> NetMessage { if q_len(net_st.net__inbox) == 0 and net_st.net__inn > 0 { net_st.net__in_on_b = not net_st.net__in_on_b net_st.net__inn = 0 } var pool = net_st.net__ina if net_st.net__in_on_b { pool = net_st.net__inb } if net_st.net__inn >= len(pool) { net__in_grow(pool) } let m = pool[net_st.net__inn] net_st.net__inn += 1 return m } export function net_spare_count(net_st: NetState) -> int { return len(net_st.net__free) } @alloc_ok("a pool miss: past the most messages in flight at once only, then kept") function net__msg_new() -> NetMsg { let m = new NetMsg m.data = buffer(NET_MTU) return m } @alloc_ok("a pool miss: past the most messages in one drain only, then kept") function net__in_grow(pool: []NetMessage) -> void { let m = new NetMessage m.data = buffer(NET_MTU) push(pool, m) } # a fact's record, from a ring made with the state: far more than a frame reports between drains const NET_FACTS_MOST: int = 64 function net__fpool__new() -> []NetFact { let xs = new []NetFact for i in 0 .. NET_FACTS_MOST { push(xs, new NetFact) } return xs } function net__fact_rec(net_st: mut NetState) -> NetFact { let f = net_st.net__fpool[net_st.net__fat] net_st.net__fat = (net_st.net__fat + 1) % len(net_st.net__fpool) return f }