Skip to content

Commit aeebda5

Browse files
gekyBartek Szatkowski
authored andcommitted
lwip: Adopted lightweight mbox implementation based on event flags
Reduces the size of an mbox object from 180 bytes (45w) to 72 bytes (18w). Since the mbox is used in many places in lwip as a lightweight message buffer, this saves roughly 1kB of ram.
1 parent fcbd664 commit aeebda5

File tree

2 files changed

+82
-22
lines changed

2 files changed

+82
-22
lines changed

features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,21 @@ u32_t sys_now(void) {
124124
err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) {
125125
if (queue_sz > MB_SIZE)
126126
error("sys_mbox_new size error\n");
127-
127+
128+
mbox->post_idx = 0;
129+
mbox->fetch_idx = 0;
128130
memset(mbox->queue, 0, sizeof(mbox->queue));
131+
129132
memset(&mbox->data, 0, sizeof(mbox->data));
130-
mbox->attr.mq_mem = mbox->queue;
131-
mbox->attr.mq_size = sizeof(mbox->queue);
132133
mbox->attr.cb_mem = &mbox->data;
133134
mbox->attr.cb_size = sizeof(mbox->data);
134-
mbox->id = osMessageQueueNew(queue_sz, sizeof(void *), &mbox->attr);
135-
return (mbox->id == NULL) ? (ERR_MEM) : (ERR_OK);
135+
mbox->id = osEventFlagsNew(&mbox->attr);
136+
if (mbox->id == NULL)
137+
error("sys_mbox_new create error\n");
138+
139+
osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT);
140+
141+
return ERR_OK;
136142
}
137143

138144
/*---------------------------------------------------------------------------*
@@ -146,7 +152,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) {
146152
* sys_mbox_t *mbox -- Handle of mailbox
147153
*---------------------------------------------------------------------------*/
148154
void sys_mbox_free(sys_mbox_t *mbox) {
149-
if (osMessageQueueGetCount(mbox->id) != 0)
155+
if (mbox->post_idx != mbox->fetch_idx)
150156
error("sys_mbox_free error\n");
151157
}
152158

@@ -160,8 +166,19 @@ void sys_mbox_free(sys_mbox_t *mbox) {
160166
* void *msg -- Pointer to data to post
161167
*---------------------------------------------------------------------------*/
162168
void sys_mbox_post(sys_mbox_t *mbox, void *msg) {
163-
if (osMessageQueuePut(mbox->id, &msg, 0, osWaitForever) != osOK)
164-
error("sys_mbox_post error\n");
169+
osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT,
170+
osFlagsWaitAny | osFlagsNoClear, osWaitForever);
171+
172+
int state = osKernelLock();
173+
174+
mbox->queue[mbox->post_idx % MB_SIZE] = msg;
175+
mbox->post_idx += 1;
176+
177+
osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT);
178+
if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1)
179+
osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT);
180+
181+
osKernelRestoreLock(state);
165182
}
166183

167184
/*---------------------------------------------------------------------------*
@@ -178,8 +195,22 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) {
178195
* if not.
179196
*---------------------------------------------------------------------------*/
180197
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) {
181-
osStatus_t status = osMessageQueuePut(mbox->id, &msg, 0, 0);
182-
return (status == osOK) ? (ERR_OK) : (ERR_MEM);
198+
uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT,
199+
osFlagsWaitAny | osFlagsNoClear, 0);
200+
if (!(flags & SYS_MBOX_POST_EVENT))
201+
return ERR_MEM;
202+
203+
int state = osKernelLock();
204+
205+
mbox->queue[mbox->post_idx % MB_SIZE] = msg;
206+
mbox->post_idx += 1;
207+
208+
osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT);
209+
if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1)
210+
osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT);
211+
212+
osKernelRestoreLock(state);
213+
return ERR_OK;
183214
}
184215

185216
/*---------------------------------------------------------------------------*
@@ -208,12 +239,23 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) {
208239
* of milliseconds until received.
209240
*---------------------------------------------------------------------------*/
210241
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) {
211-
u32_t start = us_ticker_read();
212-
213-
osStatus_t res = osMessageQueueGet(mbox->id, msg, NULL, (timeout != 0)?(timeout):(osWaitForever));
214-
if (res != osOK)
242+
uint32_t start = us_ticker_read();
243+
uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT,
244+
osFlagsWaitAny | osFlagsNoClear, (timeout ? timeout : osWaitForever));
245+
if (!(flags & SYS_MBOX_FETCH_EVENT))
215246
return SYS_ARCH_TIMEOUT;
216247

248+
int state = osKernelLock();
249+
250+
if (msg)
251+
*msg = mbox->queue[mbox->fetch_idx % MB_SIZE];
252+
mbox->fetch_idx += 1;
253+
254+
osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT);
255+
if (mbox->post_idx == mbox->fetch_idx)
256+
osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT);
257+
258+
osKernelRestoreLock(state);
217259
return (us_ticker_read() - start) / 1000;
218260
}
219261

@@ -232,10 +274,22 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) {
232274
* return ERR_OK.
233275
*---------------------------------------------------------------------------*/
234276
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) {
235-
osStatus_t res = osMessageQueueGet(mbox->id, msg, NULL, 0);
236-
if (res != osOK)
277+
uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT,
278+
osFlagsWaitAny | osFlagsNoClear, 0);
279+
if (!(flags & SYS_MBOX_FETCH_EVENT))
237280
return SYS_MBOX_EMPTY;
238281

282+
int state = osKernelLock();
283+
284+
if (msg)
285+
*msg = mbox->queue[mbox->fetch_idx % MB_SIZE];
286+
mbox->fetch_idx += 1;
287+
288+
osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT);
289+
if (mbox->post_idx == mbox->fetch_idx)
290+
osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT);
291+
292+
osKernelRestoreLock(state);
239293
return ERR_OK;
240294
}
241295

features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/sys_arch.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,21 @@ typedef struct {
4747
#define MB_SIZE 8
4848

4949
typedef struct {
50-
osMessageQueueId_t id;
51-
osMessageQueueAttr_t attr;
52-
char queue[MB_SIZE * (sizeof(void*) + sizeof(os_message_t))];
53-
os_message_queue_t data;
50+
osEventFlagsId_t id;
51+
osEventFlagsAttr_t attr;
52+
os_event_flags_t data;
53+
54+
uint8_t post_idx;
55+
uint8_t fetch_idx;
56+
void* queue[MB_SIZE];
5457
} sys_mbox_t;
5558

59+
#define SYS_MBOX_FETCH_EVENT 0x1
60+
#define SYS_MBOX_POST_EVENT 0x2
61+
5662
#define SYS_MBOX_NULL ((uint32_t) NULL)
57-
#define sys_mbox_valid(x) (((*x).id == NULL) ? 0 : 1 )
58-
#define sys_mbox_set_invalid(x) ( (*x).id = NULL )
63+
#define sys_mbox_valid(x) (((*x).id == NULL) ? 0 : 1)
64+
#define sys_mbox_set_invalid(x) ( (*x).id = NULL)
5965

6066
#if ((DEFAULT_RAW_RECVMBOX_SIZE) > (MB_SIZE)) || \
6167
((DEFAULT_UDP_RECVMBOX_SIZE) > (MB_SIZE)) || \

0 commit comments

Comments
 (0)