ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
sockpool.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file sockpool.cpp
6 * @brief Dynamic socket recycling: an LRU connection-slot pool (see sockpool.h).
7 */
8
10
11#if PC_ENABLE_SOCKPOOL
12
13void pc_sockpool_init(SockPool *p, SockSlot *slots, size_t n)
14{
15 if (!p)
16 {
17 return;
18 }
19 p->slots = slots;
20 p->n = slots ? n : 0;
21 for (size_t i = 0; i < p->n; i++)
22 {
23 p->slots[i].in_use = false;
24 p->slots[i].id = 0;
25 p->slots[i].last_used = 0;
26 }
27}
28
29SockAcq pc_sockpool_acquire(SockPool *p, uint32_t id, uint32_t now, size_t *idx, uint32_t *evicted_id)
30{
31 if (!p || !p->slots || p->n == 0)
32 {
33 return SockAcq::SOCK_ACQ_FAIL;
34 }
35
36 // Prefer a free slot.
37 for (size_t i = 0; i < p->n; i++)
38 {
39 if (!p->slots[i].in_use)
40 {
41 p->slots[i].in_use = true;
42 p->slots[i].id = id;
43 p->slots[i].last_used = now;
44 if (idx)
45 {
46 *idx = i;
47 }
48 return SockAcq::SOCK_ACQ_FREE;
49 }
50 }
51
52 // Full: recycle the least-recently-used slot.
53 size_t lru = 0;
54 for (size_t i = 1; i < p->n; i++)
55 {
56 if (p->slots[i].last_used < p->slots[lru].last_used)
57 {
58 lru = i;
59 }
60 }
61 if (evicted_id)
62 {
63 *evicted_id = p->slots[lru].id;
64 }
65 p->slots[lru].id = id;
66 p->slots[lru].last_used = now;
67 if (idx)
68 {
69 *idx = lru;
70 }
71 return SockAcq::SOCK_ACQ_RECYCLED;
72}
73
74void pc_sockpool_touch(SockPool *p, size_t idx, uint32_t now)
75{
76 if (!p || !p->slots || idx >= p->n)
77 {
78 return;
79 }
80 if (p->slots[idx].in_use)
81 {
82 p->slots[idx].last_used = now;
83 }
84}
85
86bool pc_sockpool_release(SockPool *p, size_t idx)
87{
88 if (!p || !p->slots || idx >= p->n || !p->slots[idx].in_use)
89 {
90 return false;
91 }
92 p->slots[idx].in_use = false;
93 return true;
94}
95
96bool pc_sockpool_find(const SockPool *p, uint32_t id, size_t *idx)
97{
98 if (!p || !p->slots)
99 {
100 return false;
101 }
102 for (size_t i = 0; i < p->n; i++)
103 {
104 if (p->slots[i].in_use && p->slots[i].id == id)
105 {
106 if (idx)
107 {
108 *idx = i;
109 }
110 return true;
111 }
112 }
113 return false;
114}
115
116size_t pc_sockpool_in_use(const SockPool *p)
117{
118 if (!p || !p->slots)
119 {
120 return 0;
121 }
122 size_t c = 0;
123 for (size_t i = 0; i < p->n; i++)
124 {
125 if (p->slots[i].in_use)
126 {
127 c++;
128 }
129 }
130 return c;
131}
132
133#endif // PC_ENABLE_SOCKPOOL
Dynamic socket recycling: an LRU connection-slot pool (PC_ENABLE_SOCKPOOL).