1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9 #include <cmsis_os2.h>
10 
11 #define MAX_BLOCKS      10
12 #define TIMEOUT_TICKS   10
13 
14 struct mem_block {
15 	int member1;
16 	int member2;
17 };
18 
19 static char __aligned(sizeof(void *)) sample_mem[sizeof(struct mem_block) * MAX_BLOCKS];
20 static const osMemoryPoolAttr_t mp_attrs = {
21 	.name = "TestMempool",
22 	.attr_bits = 0,
23 	.cb_mem = NULL,
24 	.cb_size = 0,
25 	.mp_mem = sample_mem,
26 	.mp_size = sizeof(struct mem_block) * MAX_BLOCKS,
27 };
28 
mempool_common_tests(osMemoryPoolId_t mp_id,const char * expected_name)29 static void mempool_common_tests(osMemoryPoolId_t mp_id,
30 				 const char *expected_name)
31 {
32 	int i;
33 	osMemoryPoolId_t dummy_id = NULL;
34 	const char *name;
35 	struct mem_block *addr_list[MAX_BLOCKS + 1];
36 	osStatus_t status;
37 
38 	zassert_true(osMemoryPoolGetName(dummy_id) == NULL,
39 		     "Something's wrong with osMemoryPoolGetName!");
40 
41 	name = osMemoryPoolGetName(mp_id);
42 	zassert_str_equal(expected_name, name, "Error getting mempool name");
43 
44 	zassert_equal(osMemoryPoolGetCapacity(dummy_id), 0,
45 		      "Something's wrong with osMemoryPoolGetCapacity!");
46 
47 	zassert_equal(osMemoryPoolGetCapacity(mp_id), MAX_BLOCKS,
48 		      "Something's wrong with osMemoryPoolGetCapacity!");
49 
50 	zassert_equal(osMemoryPoolGetBlockSize(dummy_id), 0,
51 		      "Something's wrong with osMemoryPoolGetBlockSize!");
52 
53 	zassert_equal(osMemoryPoolGetBlockSize(mp_id),
54 		      sizeof(struct mem_block),
55 		      "Something's wrong with osMemoryPoolGetBlockSize!");
56 
57 	/* The memory pool should be completely available at this point */
58 	zassert_equal(osMemoryPoolGetCount(mp_id), 0,
59 		      "Something's wrong with osMemoryPoolGetCount!");
60 	zassert_equal(osMemoryPoolGetSpace(mp_id), MAX_BLOCKS,
61 		      "Something's wrong with osMemoryPoolGetSpace!");
62 
63 	for (i = 0; i < MAX_BLOCKS; i++) {
64 		addr_list[i] = (struct mem_block *)osMemoryPoolAlloc(mp_id,
65 								     osWaitForever);
66 		zassert_true(addr_list[i] != NULL, "mempool allocation failed");
67 	}
68 
69 	/* The memory pool should be completely in use at this point */
70 	zassert_equal(osMemoryPoolGetCount(mp_id), MAX_BLOCKS,
71 		      "Something's wrong with osMemoryPoolGetCount!");
72 	zassert_equal(osMemoryPoolGetSpace(mp_id), 0,
73 		      "Something's wrong with osMemoryPoolGetSpace!");
74 
75 	/* All blocks in mempool are allocated, any more allocation
76 	 * without free should fail
77 	 */
78 	addr_list[i] = (struct mem_block *)osMemoryPoolAlloc(mp_id,
79 							     TIMEOUT_TICKS);
80 	zassert_true(addr_list[i] == NULL, "allocation happened."
81 		     " Something's wrong!");
82 
83 	zassert_equal(osMemoryPoolFree(dummy_id, addr_list[0]),
84 		      osErrorParameter, "mempool free worked unexpectedly!");
85 
86 	for (i = 0; i < MAX_BLOCKS; i++) {
87 		status = osMemoryPoolFree(mp_id, addr_list[i]);
88 		zassert_true(status == osOK, "mempool free failed");
89 	}
90 
91 	zassert_equal(osMemoryPoolDelete(dummy_id), osErrorParameter,
92 		      "mempool delete worked unexpectedly!");
93 
94 	status = osMemoryPoolDelete(mp_id);
95 	zassert_true(status == osOK, "mempool delete failure");
96 }
97 
98 /**
99  * @brief Test dynamic memory pool allocation and free
100  *
101  * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
102  */
ZTEST(cmsis_mempool,test_mempool_dynamic)103 ZTEST(cmsis_mempool, test_mempool_dynamic)
104 {
105 	osMemoryPoolId_t mp_id;
106 
107 	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block),
108 				NULL);
109 	zassert_true(mp_id != NULL, "mempool creation failed");
110 
111 	mempool_common_tests(mp_id, "ZephyrMemPool");
112 }
113 
114 /**
115  * @brief Test memory pool allocation and free
116  *
117  * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
118  */
ZTEST(cmsis_mempool,test_mempool)119 ZTEST(cmsis_mempool, test_mempool)
120 {
121 	osMemoryPoolId_t mp_id;
122 
123 	/* Create memory pool with invalid block size */
124 	mp_id = osMemoryPoolNew(MAX_BLOCKS + 1, sizeof(struct mem_block),
125 				&mp_attrs);
126 	zassert_true(mp_id == NULL, "osMemoryPoolNew worked unexpectedly!");
127 
128 	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block),
129 				&mp_attrs);
130 	zassert_true(mp_id != NULL, "mempool creation failed");
131 
132 	mempool_common_tests(mp_id, mp_attrs.name);
133 }
134 ZTEST_SUITE(cmsis_mempool, NULL, NULL, NULL, NULL, NULL);
135