• R/O
  • SSH
  • HTTPS

chibios: Commit


Commit MetaInfo

Revision13204 (tree)
Time2019-12-02 01:57:30
Authorgdisirio

Log Message

Jobs Queues test suite, there are still problems.

Change Summary

Incremental Difference

--- trunk/demos/STM32/RT-STM32L476-DISCOVERY/Makefile (revision 13203)
+++ trunk/demos/STM32/RT-STM32L476-DISCOVERY/Makefile (revision 13204)
@@ -5,7 +5,7 @@
55
66 # Compiler options here.
77 ifeq ($(USE_OPT),)
8- USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
8+ USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
99 endif
1010
1111 # C specific options here (added to USE_OPT).
--- trunk/demos/STM32/RT-STM32L476-DISCOVERY/main.c (revision 13203)
+++ trunk/demos/STM32/RT-STM32L476-DISCOVERY/main.c (revision 13204)
@@ -70,7 +70,7 @@
7070 */
7171 while (true) {
7272 if (palReadLine(LINE_JOY_CENTER)) {
73- test_execute((BaseSequentialStream *)&SD2, &rt_test_suite);
73+// test_execute((BaseSequentialStream *)&SD2, &rt_test_suite);
7474 test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite);
7575 }
7676 chThdSleepMilliseconds(500);
--- trunk/os/oslib/include/chjobs.h (revision 13203)
+++ trunk/os/oslib/include/chjobs.h (revision 13204)
@@ -42,6 +42,16 @@
4242 /* Module constants. */
4343 /*===========================================================================*/
4444
45+/**
46+ * @brief Job identifier that does nothing except cycle the dispatcher.
47+ */
48+#define JOB_NULL ((msg_t)0)
49+
50+/**
51+ * @brief Dispatcher return code in case of a @p JOB_NUL has been received.
52+ */
53+#define MSG_JOB_NULL ((msg_t)-2)
54+
4555 /*===========================================================================*/
4656 /* Module pre-compile time settings. */
4757 /*===========================================================================*/
@@ -131,10 +141,10 @@
131141 *
132142 * @init
133143 */
134-static inline void chJobsObjectInit(jobs_queue_t *jqp,
135- size_t jobsn,
136- job_descriptor_t *jobsbuf,
137- msg_t *msgbuf) {
144+static inline void chJobObjectInit(jobs_queue_t *jqp,
145+ size_t jobsn,
146+ job_descriptor_t *jobsbuf,
147+ msg_t *msgbuf) {
138148
139149 chDbgCheck((jobsn > 0U) && (jobsbuf != NULL) && (msgbuf != NULL));
140150
@@ -147,12 +157,32 @@
147157 * @brief Allocates a free job object.
148158 *
149159 * @param[in] jqp pointer to a @p jobs_queue_t structure
160+ * @param[in] timeout the number of ticks before the operation timeouts,
161+ * the following special values are allowed:
162+ * - @a TIME_IMMEDIATE immediate timeout.
163+ * - @a TIME_INFINITE no timeout.
164+ * .
150165 * @return The pointer to the allocated job object.
166+ * @retval NULL if a job object is not available within the specified
167+ * timeout.
168+ *
169+ * @api
170+ */
171+static inline job_descriptor_t *chJobGet(jobs_queue_t *jqp) {
172+
173+ return chGuardedPoolAllocTimeout(&jqp->free, TIME_INFINITE);
174+}
175+
176+/**
177+ * @brief Allocates a free job object.
178+ *
179+ * @param[in] jqp pointer to a @p jobs_queue_t structure
180+ * @return The pointer to the allocated job object.
151181 * @retval NULL if a job object is not immediately available.
152182 *
153183 * @iclass
154184 */
155-static inline job_descriptor_t *chGetTakeI(jobs_queue_t *jqp) {
185+static inline job_descriptor_t *chJobGetI(jobs_queue_t *jqp) {
156186
157187 return chGuardedPoolAllocI(&jqp->free);
158188 }
@@ -172,8 +202,8 @@
172202 *
173203 * @sclass
174204 */
175-static inline job_descriptor_t *chJobsGetTimeoutS(jobs_queue_t *jqp,
176- sysinterval_t timeout) {
205+static inline job_descriptor_t *chJobGetTimeoutS(jobs_queue_t *jqp,
206+ sysinterval_t timeout) {
177207
178208 return chGuardedPoolAllocTimeoutS(&jqp->free, timeout);
179209 }
@@ -193,8 +223,8 @@
193223 *
194224 * @api
195225 */
196-static inline job_descriptor_t *chJobsGetTimeout(jobs_queue_t *jqp,
197- sysinterval_t timeout) {
226+static inline job_descriptor_t *chJobGetTimeout(jobs_queue_t *jqp,
227+ sysinterval_t timeout) {
198228
199229 return chGuardedPoolAllocTimeout(&jqp->free, timeout);
200230 }
@@ -208,7 +238,7 @@
208238 *
209239 * @iclass
210240 */
211-static inline void chJobsPostI(jobs_queue_t *jqp, job_descriptor_t *jp) {
241+static inline void chJobPostI(jobs_queue_t *jqp, job_descriptor_t *jp) {
212242 msg_t msg;
213243
214244 msg = chMBPostI(&jqp->mbx, (msg_t)jp);
@@ -224,7 +254,7 @@
224254 *
225255 * @sclass
226256 */
227-static inline void chJobsPostS(jobs_queue_t *jqp, job_descriptor_t *jp) {
257+static inline void chJobPostS(jobs_queue_t *jqp, job_descriptor_t *jp) {
228258 msg_t msg;
229259
230260 msg = chMBPostTimeoutS(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
@@ -240,7 +270,7 @@
240270 *
241271 * @api
242272 */
243-static inline void chJobsPost(jobs_queue_t *jqp, job_descriptor_t *jp) {
273+static inline void chJobPost(jobs_queue_t *jqp, job_descriptor_t *jp) {
244274 msg_t msg;
245275
246276 msg = chMBPostTimeout(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
@@ -256,7 +286,7 @@
256286 *
257287 * @iclass
258288 */
259-static inline void chJobsPostAheadI(jobs_queue_t *jqp, job_descriptor_t *jp) {
289+static inline void chJobPostAheadI(jobs_queue_t *jqp, job_descriptor_t *jp) {
260290 msg_t msg;
261291
262292 msg = chMBPostAheadI(&jqp->mbx, (msg_t)jp);
@@ -272,7 +302,7 @@
272302 *
273303 * @sclass
274304 */
275-static inline void chJobsPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp) {
305+static inline void chJobPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp) {
276306 msg_t msg;
277307
278308 msg = chMBPostAheadTimeoutS(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
@@ -288,7 +318,7 @@
288318 *
289319 * @api
290320 */
291-static inline void chJobsPostAhead(jobs_queue_t *jqp, job_descriptor_t *jp) {
321+static inline void chJobPostAhead(jobs_queue_t *jqp, job_descriptor_t *jp) {
292322 msg_t msg;
293323
294324 msg = chMBPostAheadTimeout(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
@@ -302,19 +332,26 @@
302332 * @return The function outcome.
303333 * @retval MSG_OK if a job has been executed.
304334 * @retval MSG_RESET if the internal mailbox has been reset.
335+ * @retval MSG_JOB_NULL if a @p JOB_NULL has been received.
305336 */
306-static inline msg_t chJobsDispatch(jobs_queue_t *jqp) {
337+static inline msg_t chJobDispatch(jobs_queue_t *jqp) {
307338 msg_t msg, jmsg;
308339
340+ /* Waiting for a job.*/
309341 msg = chMBFetchTimeout(&jqp->mbx, &jmsg, TIME_INFINITE);
310342 if (msg == MSG_OK) {
311- job_descriptor_t *jp = (job_descriptor_t *)jmsg;
343+ if (jmsg != JOB_NULL) {
344+ job_descriptor_t *jp = (job_descriptor_t *)jmsg;
312345
313- /* Invoking the job function.*/
314- jp->jobfunc(jp->jobarg);
346+ /* Invoking the job function.*/
347+ jp->jobfunc(jp->jobarg);
315348
316- /* Returning the job descriptor object.*/
317- chGuardedPoolFree(&jqp->free, (void *)jp);
349+ /* Returning the job descriptor object.*/
350+ chGuardedPoolFree(&jqp->free, (void *)jp);
351+ }
352+ else {
353+ msg = MSG_JOB_NULL;
354+ }
318355 }
319356
320357 return msg;
@@ -328,20 +365,27 @@
328365 * @retval MSG_OK if a job has been executed.
329366 * @retval MSG_TIMEOUT if a timeout occurred.
330367 * @retval MSG_RESET if the internal mailbox has been reset.
368+ * @retval MSG_JOB_NULL if a @p JOB_NULL has been received.
331369 */
332-static inline msg_t chJobsDispatchTimeout(jobs_queue_t *jqp,
333- sysinterval_t timeout) {
370+static inline msg_t chJobDispatchTimeout(jobs_queue_t *jqp,
371+ sysinterval_t timeout) {
334372 msg_t msg, jmsg;
335373
374+ /* Waiting for a job or a timeout.*/
336375 msg = chMBFetchTimeout(&jqp->mbx, &jmsg, timeout);
337376 if (msg == MSG_OK) {
338- job_descriptor_t *jp = (job_descriptor_t *)jmsg;
377+ if (jmsg != JOB_NULL) {
378+ job_descriptor_t *jp = (job_descriptor_t *)jmsg;
339379
340- /* Invoking the job function.*/
341- jp->jobfunc(jp->jobarg);
380+ /* Invoking the job function.*/
381+ jp->jobfunc(jp->jobarg);
342382
343- /* Returning the job descriptor object.*/
344- chGuardedPoolFree(&jqp->free, (void *)jp);
383+ /* Returning the job descriptor object.*/
384+ chGuardedPoolFree(&jqp->free, (void *)jp);
385+ }
386+ else {
387+ msg = MSG_JOB_NULL;
388+ }
345389 }
346390
347391 return msg;
--- trunk/test/oslib/source/test/oslib_test_root.c (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_root.c (revision 13204)
@@ -29,6 +29,7 @@
2929 * - @subpage oslib_test_sequence_006
3030 * - @subpage oslib_test_sequence_007
3131 * - @subpage oslib_test_sequence_008
32+ * - @subpage oslib_test_sequence_009
3233 * .
3334 */
3435
@@ -57,21 +58,24 @@
5758 #if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
5859 &oslib_test_sequence_003,
5960 #endif
60-#if (CH_CFG_USE_DELEGATES) || defined(__DOXYGEN__)
61+#if (CH_CFG_USE_JOBS) || defined(__DOXYGEN__)
6162 &oslib_test_sequence_004,
6263 #endif
63-#if (CH_CFG_USE_OBJ_CACHES) || defined(__DOXYGEN__)
64+#if (CH_CFG_USE_DELEGATES) || defined(__DOXYGEN__)
6465 &oslib_test_sequence_005,
6566 #endif
66-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
67+#if (CH_CFG_USE_OBJ_CACHES) || defined(__DOXYGEN__)
6768 &oslib_test_sequence_006,
6869 #endif
69-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
70+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
7071 &oslib_test_sequence_007,
7172 #endif
72-#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
73+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
7374 &oslib_test_sequence_008,
7475 #endif
76+#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
77+ &oslib_test_sequence_009,
78+#endif
7579 NULL
7680 };
7781
--- trunk/test/oslib/source/test/oslib_test_root.h (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_root.h (revision 13204)
@@ -32,6 +32,7 @@
3232 #include "oslib_test_sequence_006.h"
3333 #include "oslib_test_sequence_007.h"
3434 #include "oslib_test_sequence_008.h"
35+#include "oslib_test_sequence_009.h"
3536
3637 #if !defined(__DOXYGEN__)
3738
--- trunk/test/oslib/source/test/oslib_test_sequence_004.c (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_sequence_004.c (revision 13204)
@@ -21,18 +21,18 @@
2121 * @file oslib_test_sequence_004.c
2222 * @brief Test Sequence 004 code.
2323 *
24- * @page oslib_test_sequence_004 [4] Thread Delegates
24+ * @page oslib_test_sequence_004 [4] Jobs Queues
2525 *
2626 * File: @ref oslib_test_sequence_004.c
2727 *
2828 * <h2>Description</h2>
2929 * This sequence tests the ChibiOS library functionalities related to
30- * Thread Delegates.
30+ * Jobs Queues.
3131 *
3232 * <h2>Conditions</h2>
3333 * This sequence is only executed if the following preprocessor condition
3434 * evaluates to true:
35- * - CH_CFG_USE_DELEGATES
35+ * - CH_CFG_USE_JOBS
3636 * .
3737 *
3838 * <h2>Test Cases</h2>
@@ -40,74 +40,34 @@
4040 * .
4141 */
4242
43-#if (CH_CFG_USE_DELEGATES) || defined(__DOXYGEN__)
43+#if (CH_CFG_USE_JOBS) || defined(__DOXYGEN__)
4444
4545 /****************************************************************************
4646 * Shared code.
4747 ****************************************************************************/
4848
49-static bool exit_flag;
49+#define JOBS_QUEUE_SIZE 4
5050
51-static int dis_func0(void) {
51+static jobs_queue_t jq;
52+static job_descriptor_t jobs[JOBS_QUEUE_SIZE];
53+static msg_t msg_queue[JOBS_QUEUE_SIZE];
5254
53- test_emit_token('0');
55+static void job_slow(void *arg) {
5456
55- return 0x55AA;
57+ test_emit_token((int)arg);
58+ chThdSleepMilliseconds(10);
5659 }
5760
58-static char dis_func1(char a) {
59-
60- test_emit_token((char)a);
61-
62- return a;
63-}
64-
65-static char dis_func2(char a, char b) {
66-
67- test_emit_token((char)a);
68- test_emit_token((char)b);
69-
70- return a;
71-}
72-
73-static char dis_func3(char a, char b, char c) {
74-
75- test_emit_token((char)a);
76- test_emit_token((char)b);
77- test_emit_token((char)c);
78-
79- return a;
80-}
81-
82-static char dis_func4(char a, char b, char c, char d) {
83-
84- test_emit_token((char)a);
85- test_emit_token((char)b);
86- test_emit_token((char)c);
87- test_emit_token((char)d);
88-
89- return a;
90-}
91-
92-static int dis_func_end(void) {
93-
94- test_emit_token('Z');
95- exit_flag = true;
96-
97- return 0xAA55;
98-}
99-
100-static THD_WORKING_AREA(waThread1, 256);
61+static THD_WORKING_AREA(wa1Thread1, 256);
62+static THD_WORKING_AREA(wa2Thread1, 256);
10163 static THD_FUNCTION(Thread1, arg) {
64+ msg_t msg;
10265
10366 (void)arg;
10467
105- exit_flag = false;
10668 do {
107- chDelegateDispatch();
108- } while (!exit_flag);
109-
110- chThdExit(0x0FA5);
69+ msg = chJobDispatch(&jq);
70+ } while (msg == MSG_OK);
11171 }
11272
11373 /****************************************************************************
@@ -121,66 +81,73 @@
12181 * The dispatcher API is tested for functionality.
12282 *
12383 * <h2>Test Steps</h2>
124- * - [4.1.1] Starting the dispatcher thread.
125- * - [4.1.2] Calling the default veneers, checking the result and the
126- * emitted tokens.
127- * - [4.1.3] Waiting for the thread to terminate-.
84+ * - [4.1.1] Initializing the Jobs Queue object.
85+ * - [4.1.2] Starting the dispatcher threads.
86+ * - [4.1.3] Sending jobs with various timings.
87+ * - [4.1.4] Sending null jobs to make thread exit.
12888 * .
12989 */
13090
13191 static void oslib_test_004_001_execute(void) {
132- thread_t *tp;
92+ thread_t *tp1, *tp2;
13393
134- /* [4.1.1] Starting the dispatcher thread.*/
94+ /* [4.1.1] Initializing the Jobs Queue object.*/
13595 test_set_step(1);
13696 {
137- thread_descriptor_t td = {
138- .name = "dispatcher",
139- .wbase = waThread1,
140- .wend = THD_WORKING_AREA_END(waThread1),
141- .prio = chThdGetPriorityX() + 1,
142- .funcp = Thread1,
143- .arg = NULL
144- };
145- tp = chThdCreate(&td);
97+ chJobObjectInit(&jq, JOBS_QUEUE_SIZE, jobs, msg_queue);
14698 }
14799 test_end_step(1);
148100
149- /* [4.1.2] Calling the default veneers, checking the result and the
150- emitted tokens.*/
101+ /* [4.1.2] Starting the dispatcher threads.*/
151102 test_set_step(2);
152103 {
153- int retval;
104+ thread_descriptor_t td1 = {
105+ .name = "dispatcher1",
106+ .wbase = wa1Thread1,
107+ .wend = THD_WORKING_AREA_END(wa1Thread1),
108+ .prio = chThdGetPriorityX() - 1,
109+ .funcp = Thread1,
110+ .arg = NULL
111+ };
112+ tp1 = chThdCreate(&td1);
154113
155- retval = chDelegateCallDirect0(tp, (delegate_fn0_t)dis_func0);
156- test_assert(retval == 0x55AA, "invalid return value");
157-
158- retval = chDelegateCallDirect1(tp, (delegate_fn1_t)dis_func1, 'A');
159- test_assert(retval == (int)'A', "invalid return value");
160-
161- retval = chDelegateCallDirect2(tp, (delegate_fn2_t)dis_func2, 'B', 'C');
162- test_assert(retval == (int)'B', "invalid return value");
163-
164- retval = chDelegateCallDirect3(tp, (delegate_fn3_t)dis_func3, 'D', 'E', 'F');
165- test_assert(retval == (int)'D', "invalid return value");
166-
167- retval = chDelegateCallDirect4(tp, (delegate_fn4_t)dis_func4, 'G', 'H', 'I', 'J');
168- test_assert(retval == (int)'G', "invalid return value");
169-
170- retval = chDelegateCallDirect0(tp, (delegate_fn0_t)dis_func_end);
171- test_assert(retval == 0xAA55, "invalid return value");
172-
173- test_assert_sequence("0ABCDEFGHIJZ", "unexpected tokens");
114+ thread_descriptor_t td2 = {
115+ .name = "dispatcher2",
116+ .wbase = wa2Thread1,
117+ .wend = THD_WORKING_AREA_END(wa2Thread1),
118+ .prio = chThdGetPriorityX() - 1,
119+ .funcp = Thread1,
120+ .arg = NULL
121+ };
122+ tp2 = chThdCreate(&td2);
174123 }
175124 test_end_step(2);
176125
177- /* [4.1.3] Waiting for the thread to terminate-.*/
126+ /* [4.1.3] Sending jobs with various timings.*/
178127 test_set_step(3);
179128 {
180- msg_t msg = chThdWait(tp);
181- test_assert(msg == 0x0FA5, "invalid exit code");
129+ unsigned i;
130+ job_descriptor_t *jdp;
131+
132+ for (i = 0; i < 8; i++) {
133+ jdp = chJobGet(&jq);
134+ jdp->jobfunc = job_slow;
135+ jdp->jobarg = (void *)('a' + i);
136+ chJobPost(&jq, jdp);
137+ }
182138 }
183139 test_end_step(3);
140+
141+ /* [4.1.4] Sending null jobs to make thread exit.*/
142+ test_set_step(4);
143+ {
144+ chJobPost(&jq, JOB_NULL);
145+ chJobPost(&jq, JOB_NULL);
146+ (void) chThdWait(tp1);
147+ (void) chThdWait(tp2);
148+ test_assert_sequence("abcdefgh", "unexpected tokens");
149+ }
150+ test_end_step(4);
184151 }
185152
186153 static const testcase_t oslib_test_004_001 = {
@@ -203,11 +170,11 @@
203170 };
204171
205172 /**
206- * @brief Thread Delegates.
173+ * @brief Jobs Queues.
207174 */
208175 const testsequence_t oslib_test_sequence_004 = {
209- "Thread Delegates",
176+ "Jobs Queues",
210177 oslib_test_sequence_004_array
211178 };
212179
213-#endif /* CH_CFG_USE_DELEGATES */
180+#endif /* CH_CFG_USE_JOBS */
--- trunk/test/oslib/source/test/oslib_test_sequence_005.c (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_sequence_005.c (revision 13204)
@@ -21,18 +21,18 @@
2121 * @file oslib_test_sequence_005.c
2222 * @brief Test Sequence 005 code.
2323 *
24- * @page oslib_test_sequence_005 [5] Objects Caches
24+ * @page oslib_test_sequence_005 [5] Thread Delegates
2525 *
2626 * File: @ref oslib_test_sequence_005.c
2727 *
2828 * <h2>Description</h2>
2929 * This sequence tests the ChibiOS library functionalities related to
30- * Objects Caches.
30+ * Thread Delegates.
3131 *
3232 * <h2>Conditions</h2>
3333 * This sequence is only executed if the following preprocessor condition
3434 * evaluates to true:
35- * - CH_CFG_USE_OBJ_CACHES
35+ * - CH_CFG_USE_DELEGATES
3636 * .
3737 *
3838 * <h2>Test Cases</h2>
@@ -40,204 +40,151 @@
4040 * .
4141 */
4242
43-#if (CH_CFG_USE_OBJ_CACHES) || defined(__DOXYGEN__)
43+#if (CH_CFG_USE_DELEGATES) || defined(__DOXYGEN__)
4444
4545 /****************************************************************************
4646 * Shared code.
4747 ****************************************************************************/
4848
49-#include <string.h>
49+static bool exit_flag;
5050
51-#define SIZE_OBJECTS 16
52-#define NUM_OBJECTS 4
53-#define NUM_HASH_ENTRIES (NUM_OBJECTS * 2)
51+static int dis_func0(void) {
5452
55-/* Cached object type used for test.*/
56-typedef struct {
57- oc_object_t header;
58- uint8_t data[SIZE_OBJECTS];
59-} cached_object_t;
53+ test_emit_token('0');
6054
61-static oc_hash_header_t hash_headers[NUM_HASH_ENTRIES];
62-static cached_object_t objects[NUM_OBJECTS];
63-static objects_cache_t cache1;
55+ return 0x55AA;
56+}
6457
65-static bool obj_read(objects_cache_t *ocp,
66- oc_object_t *objp,
67- bool async) {
58+static char dis_func1(char a) {
6859
69- test_emit_token('a' + objp->obj_key);
60+ test_emit_token((char)a);
7061
71- objp->obj_flags &= ~OC_FLAG_NOTSYNC;
62+ return a;
63+}
7264
73- if (async) {
74- chCacheReleaseObject(ocp, objp);
75- }
65+static char dis_func2(char a, char b) {
7666
77- return false;
67+ test_emit_token((char)a);
68+ test_emit_token((char)b);
69+
70+ return a;
7871 }
7972
80-static bool obj_write(objects_cache_t *ocp,
81- oc_object_t *objp,
82- bool async) {
83- (void)ocp;
84- (void)async;
73+static char dis_func3(char a, char b, char c) {
8574
86- test_emit_token('A' + objp->obj_key);
75+ test_emit_token((char)a);
76+ test_emit_token((char)b);
77+ test_emit_token((char)c);
8778
88- return false;
79+ return a;
8980 }
9081
82+static char dis_func4(char a, char b, char c, char d) {
83+
84+ test_emit_token((char)a);
85+ test_emit_token((char)b);
86+ test_emit_token((char)c);
87+ test_emit_token((char)d);
88+
89+ return a;
90+}
91+
92+static int dis_func_end(void) {
93+
94+ test_emit_token('Z');
95+ exit_flag = true;
96+
97+ return 0xAA55;
98+}
99+
100+static THD_WORKING_AREA(waThread1, 256);
101+static THD_FUNCTION(Thread1, arg) {
102+
103+ (void)arg;
104+
105+ exit_flag = false;
106+ do {
107+ chDelegateDispatch();
108+ } while (!exit_flag);
109+
110+ chThdExit(0x0FA5);
111+}
112+
91113 /****************************************************************************
92114 * Test cases.
93115 ****************************************************************************/
94116
95117 /**
96- * @page oslib_test_005_001 [5.1] Cache initialization
118+ * @page oslib_test_005_001 [5.1] Dispatcher test
97119 *
98120 * <h2>Description</h2>
99- * A cache object is initialized, some initial conditions are checked.
121+ * The dispatcher API is tested for functionality.
100122 *
101123 * <h2>Test Steps</h2>
102- * - [5.1.1] Cache initialization.
103- * - [5.1.2] Getting and releasing objects without initialization.
104- * - [5.1.3] Getting and releasing objects with synchronous
105- * initialization.
106- * - [5.1.4] Getting and releasing objects with asynchronous
107- * initialization.
108- * - [5.1.5] Checking cached objects.
109- * - [5.1.6] Checking non-cached objects.
124+ * - [5.1.1] Starting the dispatcher thread.
125+ * - [5.1.2] Calling the default veneers, checking the result and the
126+ * emitted tokens.
127+ * - [5.1.3] Waiting for the thread to terminate-.
110128 * .
111129 */
112130
113131 static void oslib_test_005_001_execute(void) {
132+ thread_t *tp;
114133
115- /* [5.1.1] Cache initialization.*/
134+ /* [5.1.1] Starting the dispatcher thread.*/
116135 test_set_step(1);
117136 {
118- chCacheObjectInit(&cache1,
119- NUM_HASH_ENTRIES,
120- hash_headers,
121- NUM_OBJECTS,
122- sizeof (cached_object_t),
123- objects,
124- obj_read,
125- obj_write);
137+ thread_descriptor_t td = {
138+ .name = "dispatcher",
139+ .wbase = waThread1,
140+ .wend = THD_WORKING_AREA_END(waThread1),
141+ .prio = chThdGetPriorityX() + 1,
142+ .funcp = Thread1,
143+ .arg = NULL
144+ };
145+ tp = chThdCreate(&td);
126146 }
127147 test_end_step(1);
128148
129- /* [5.1.2] Getting and releasing objects without initialization.*/
149+ /* [5.1.2] Calling the default veneers, checking the result and the
150+ emitted tokens.*/
130151 test_set_step(2);
131152 {
132- uint32_t i;
153+ int retval;
133154
134- for (i = 0; i < (NUM_OBJECTS * 2); i++) {
135- oc_object_t * objp = chCacheGetObject(&cache1, 0U, i);
155+ retval = chDelegateCallDirect0(tp, (delegate_fn0_t)dis_func0);
156+ test_assert(retval == 0x55AA, "invalid return value");
136157
137- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
138- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "should not be in sync");
158+ retval = chDelegateCallDirect1(tp, (delegate_fn1_t)dis_func1, 'A');
159+ test_assert(retval == (int)'A', "invalid return value");
139160
140- chCacheReleaseObject(&cache1, objp);
141- }
161+ retval = chDelegateCallDirect2(tp, (delegate_fn2_t)dis_func2, 'B', 'C');
162+ test_assert(retval == (int)'B', "invalid return value");
142163
143- test_assert_sequence("", "unexpected tokens");
164+ retval = chDelegateCallDirect3(tp, (delegate_fn3_t)dis_func3, 'D', 'E', 'F');
165+ test_assert(retval == (int)'D', "invalid return value");
166+
167+ retval = chDelegateCallDirect4(tp, (delegate_fn4_t)dis_func4, 'G', 'H', 'I', 'J');
168+ test_assert(retval == (int)'G', "invalid return value");
169+
170+ retval = chDelegateCallDirect0(tp, (delegate_fn0_t)dis_func_end);
171+ test_assert(retval == 0xAA55, "invalid return value");
172+
173+ test_assert_sequence("0ABCDEFGHIJZ", "unexpected tokens");
144174 }
145175 test_end_step(2);
146176
147- /* [5.1.3] Getting and releasing objects with synchronous
148- initialization.*/
177+ /* [5.1.3] Waiting for the thread to terminate-.*/
149178 test_set_step(3);
150179 {
151- uint32_t i;
152- bool error;
153-
154- for (i = 0; i < (NUM_OBJECTS * 2); i++) {
155- oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
156-
157- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
158- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "in sync");
159-
160- error = chCacheReadObject(&cache1, objp, false);
161-
162- test_assert(error == false, "returned error");
163- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
164- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) == 0U, "not in sync");
165-
166- chCacheReleaseObject(&cache1, objp);
167- }
168-
169- test_assert_sequence("abcdefgh", "unexpected tokens");
180+ msg_t msg = chThdWait(tp);
181+ test_assert(msg == 0x0FA5, "invalid exit code");
170182 }
171183 test_end_step(3);
172-
173- /* [5.1.4] Getting and releasing objects with asynchronous
174- initialization.*/
175- test_set_step(4);
176- {
177- uint32_t i;
178- bool error;
179-
180- for (i = 0; i < (NUM_OBJECTS * 2); i++) {
181- oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
182-
183- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
184- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "in sync");
185-
186- error = chCacheReadObject(&cache1, objp, true);
187-
188- test_assert(error == false, "returned error");
189-
190- objp = chCacheGetObject(&cache1, 0U, i);
191-
192- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
193- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) == 0U, "not in sync");
194-
195- chCacheReleaseObject(&cache1, objp);
196- }
197-
198- test_assert_sequence("abcdefgh", "unexpected tokens");
199- }
200- test_end_step(4);
201-
202- /* [5.1.5] Checking cached objects.*/
203- test_set_step(5);
204- {
205- uint32_t i;
206-
207- for (i = NUM_OBJECTS; i < (NUM_OBJECTS * 2); i++) {
208- oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
209-
210- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
211- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) == 0U, "not in sync");
212-
213- chCacheReleaseObject(&cache1, objp);
214- }
215-
216- test_assert_sequence("", "unexpected tokens");
217- }
218- test_end_step(5);
219-
220- /* [5.1.6] Checking non-cached objects.*/
221- test_set_step(6);
222- {
223- uint32_t i;
224-
225- for (i = 0; i < NUM_OBJECTS; i++) {
226- oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
227-
228- test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
229- test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "in sync");
230-
231- chCacheReleaseObject(&cache1, objp);
232- }
233-
234- test_assert_sequence("", "unexpected tokens");
235- }
236- test_end_step(6);
237184 }
238185
239186 static const testcase_t oslib_test_005_001 = {
240- "Cache initialization",
187+ "Dispatcher test",
241188 NULL,
242189 NULL,
243190 oslib_test_005_001_execute
@@ -256,11 +203,11 @@
256203 };
257204
258205 /**
259- * @brief Objects Caches.
206+ * @brief Thread Delegates.
260207 */
261208 const testsequence_t oslib_test_sequence_005 = {
262- "Objects Caches",
209+ "Thread Delegates",
263210 oslib_test_sequence_005_array
264211 };
265212
266-#endif /* CH_CFG_USE_OBJ_CACHES */
213+#endif /* CH_CFG_USE_DELEGATES */
--- trunk/test/oslib/source/test/oslib_test_sequence_006.c (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_sequence_006.c (revision 13204)
@@ -21,272 +21,227 @@
2121 * @file oslib_test_sequence_006.c
2222 * @brief Test Sequence 006 code.
2323 *
24- * @page oslib_test_sequence_006 [6] Memory Pools
24+ * @page oslib_test_sequence_006 [6] Objects Caches
2525 *
2626 * File: @ref oslib_test_sequence_006.c
2727 *
2828 * <h2>Description</h2>
2929 * This sequence tests the ChibiOS library functionalities related to
30- * memory pools.
30+ * Objects Caches.
3131 *
3232 * <h2>Conditions</h2>
3333 * This sequence is only executed if the following preprocessor condition
3434 * evaluates to true:
35- * - CH_CFG_USE_MEMPOOLS
35+ * - CH_CFG_USE_OBJ_CACHES
3636 * .
3737 *
3838 * <h2>Test Cases</h2>
3939 * - @subpage oslib_test_006_001
40- * - @subpage oslib_test_006_002
41- * - @subpage oslib_test_006_003
4240 * .
4341 */
4442
45-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
43+#if (CH_CFG_USE_OBJ_CACHES) || defined(__DOXYGEN__)
4644
4745 /****************************************************************************
4846 * Shared code.
4947 ****************************************************************************/
5048
51-#define MEMORY_POOL_SIZE 4
49+#include <string.h>
5250
53-static uint32_t objects[MEMORY_POOL_SIZE];
54-static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
51+#define SIZE_OBJECTS 16
52+#define NUM_OBJECTS 4
53+#define NUM_HASH_ENTRIES (NUM_OBJECTS * 2)
5554
56-#if CH_CFG_USE_SEMAPHORES
57-static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
58-#endif
55+/* Cached object type used for test.*/
56+typedef struct {
57+ oc_object_t header;
58+ uint8_t data[SIZE_OBJECTS];
59+} cached_object_t;
5960
60-static void *null_provider(size_t size, unsigned align) {
61+static oc_hash_header_t hash_headers[NUM_HASH_ENTRIES];
62+static cached_object_t objects[NUM_OBJECTS];
63+static objects_cache_t cache1;
6164
62- (void)size;
63- (void)align;
65+static bool obj_read(objects_cache_t *ocp,
66+ oc_object_t *objp,
67+ bool async) {
6468
65- return NULL;
69+ test_emit_token('a' + objp->obj_key);
70+
71+ objp->obj_flags &= ~OC_FLAG_NOTSYNC;
72+
73+ if (async) {
74+ chCacheReleaseObject(ocp, objp);
75+ }
76+
77+ return false;
6678 }
6779
80+static bool obj_write(objects_cache_t *ocp,
81+ oc_object_t *objp,
82+ bool async) {
83+ (void)ocp;
84+ (void)async;
85+
86+ test_emit_token('A' + objp->obj_key);
87+
88+ return false;
89+}
90+
6891 /****************************************************************************
6992 * Test cases.
7093 ****************************************************************************/
7194
7295 /**
73- * @page oslib_test_006_001 [6.1] Loading and emptying a memory pool
96+ * @page oslib_test_006_001 [6.1] Cache initialization
7497 *
7598 * <h2>Description</h2>
76- * The memory pool functionality is tested by loading and emptying it,
77- * all conditions are tested.
99+ * A cache object is initialized, some initial conditions are checked.
78100 *
79101 * <h2>Test Steps</h2>
80- * - [6.1.1] Adding the objects to the pool using chPoolLoadArray().
81- * - [6.1.2] Emptying the pool using chPoolAlloc().
82- * - [6.1.3] Now must be empty.
83- * - [6.1.4] Adding the objects to the pool using chPoolFree().
84- * - [6.1.5] Emptying the pool using chPoolAlloc() again.
85- * - [6.1.6] Now must be empty again.
86- * - [6.1.7] Covering the case where a provider is unable to return
87- * more memory.
102+ * - [6.1.1] Cache initialization.
103+ * - [6.1.2] Getting and releasing objects without initialization.
104+ * - [6.1.3] Getting and releasing objects with synchronous
105+ * initialization.
106+ * - [6.1.4] Getting and releasing objects with asynchronous
107+ * initialization.
108+ * - [6.1.5] Checking cached objects.
109+ * - [6.1.6] Checking non-cached objects.
88110 * .
89111 */
90112
91-static void oslib_test_006_001_setup(void) {
92- chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
93-}
94-
95113 static void oslib_test_006_001_execute(void) {
96- unsigned i;
97114
98- /* [6.1.1] Adding the objects to the pool using chPoolLoadArray().*/
115+ /* [6.1.1] Cache initialization.*/
99116 test_set_step(1);
100117 {
101- chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
118+ chCacheObjectInit(&cache1,
119+ NUM_HASH_ENTRIES,
120+ hash_headers,
121+ NUM_OBJECTS,
122+ sizeof (cached_object_t),
123+ objects,
124+ obj_read,
125+ obj_write);
102126 }
103127 test_end_step(1);
104128
105- /* [6.1.2] Emptying the pool using chPoolAlloc().*/
129+ /* [6.1.2] Getting and releasing objects without initialization.*/
106130 test_set_step(2);
107131 {
108- for (i = 0; i < MEMORY_POOL_SIZE; i++)
109- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
132+ uint32_t i;
133+
134+ for (i = 0; i < (NUM_OBJECTS * 2); i++) {
135+ oc_object_t * objp = chCacheGetObject(&cache1, 0U, i);
136+
137+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
138+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "should not be in sync");
139+
140+ chCacheReleaseObject(&cache1, objp);
141+ }
142+
143+ test_assert_sequence("", "unexpected tokens");
110144 }
111145 test_end_step(2);
112146
113- /* [6.1.3] Now must be empty.*/
147+ /* [6.1.3] Getting and releasing objects with synchronous
148+ initialization.*/
114149 test_set_step(3);
115150 {
116- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
151+ uint32_t i;
152+ bool error;
153+
154+ for (i = 0; i < (NUM_OBJECTS * 2); i++) {
155+ oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
156+
157+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
158+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "in sync");
159+
160+ error = chCacheReadObject(&cache1, objp, false);
161+
162+ test_assert(error == false, "returned error");
163+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
164+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) == 0U, "not in sync");
165+
166+ chCacheReleaseObject(&cache1, objp);
167+ }
168+
169+ test_assert_sequence("abcdefgh", "unexpected tokens");
117170 }
118171 test_end_step(3);
119172
120- /* [6.1.4] Adding the objects to the pool using chPoolFree().*/
173+ /* [6.1.4] Getting and releasing objects with asynchronous
174+ initialization.*/
121175 test_set_step(4);
122176 {
123- for (i = 0; i < MEMORY_POOL_SIZE; i++)
124- chPoolFree(&mp1, &objects[i]);
125- }
126- test_end_step(4);
177+ uint32_t i;
178+ bool error;
127179
128- /* [6.1.5] Emptying the pool using chPoolAlloc() again.*/
129- test_set_step(5);
130- {
131- for (i = 0; i < MEMORY_POOL_SIZE; i++)
132- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
133- }
134- test_end_step(5);
180+ for (i = 0; i < (NUM_OBJECTS * 2); i++) {
181+ oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
135182
136- /* [6.1.6] Now must be empty again.*/
137- test_set_step(6);
138- {
139- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
140- }
141- test_end_step(6);
183+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
184+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "in sync");
142185
143- /* [6.1.7] Covering the case where a provider is unable to return
144- more memory.*/
145- test_set_step(7);
146- {
147- chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
148- test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
149- }
150- test_end_step(7);
151-}
186+ error = chCacheReadObject(&cache1, objp, true);
152187
153-static const testcase_t oslib_test_006_001 = {
154- "Loading and emptying a memory pool",
155- oslib_test_006_001_setup,
156- NULL,
157- oslib_test_006_001_execute
158-};
188+ test_assert(error == false, "returned error");
159189
160-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
161-/**
162- * @page oslib_test_006_002 [6.2] Loading and emptying a guarded memory pool without waiting
163- *
164- * <h2>Description</h2>
165- * The memory pool functionality is tested by loading and emptying it,
166- * all conditions are tested.
167- *
168- * <h2>Conditions</h2>
169- * This test is only executed if the following preprocessor condition
170- * evaluates to true:
171- * - CH_CFG_USE_SEMAPHORES
172- * .
173- *
174- * <h2>Test Steps</h2>
175- * - [6.2.1] Adding the objects to the pool using
176- * chGuardedPoolLoadArray().
177- * - [6.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
178- * - [6.2.3] Now must be empty.
179- * - [6.2.4] Adding the objects to the pool using chGuardedPoolFree().
180- * - [6.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
181- * - [6.2.6] Now must be empty again.
182- * .
183- */
190+ objp = chCacheGetObject(&cache1, 0U, i);
184191
185-static void oslib_test_006_002_setup(void) {
186- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
187-}
192+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
193+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) == 0U, "not in sync");
188194
189-static void oslib_test_006_002_execute(void) {
190- unsigned i;
195+ chCacheReleaseObject(&cache1, objp);
196+ }
191197
192- /* [6.2.1] Adding the objects to the pool using
193- chGuardedPoolLoadArray().*/
194- test_set_step(1);
195- {
196- chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
198+ test_assert_sequence("abcdefgh", "unexpected tokens");
197199 }
198- test_end_step(1);
200+ test_end_step(4);
199201
200- /* [6.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
201- test_set_step(2);
202+ /* [6.1.5] Checking cached objects.*/
203+ test_set_step(5);
202204 {
203- for (i = 0; i < MEMORY_POOL_SIZE; i++)
204- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
205- }
206- test_end_step(2);
205+ uint32_t i;
207206
208- /* [6.2.3] Now must be empty.*/
209- test_set_step(3);
210- {
211- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
212- }
213- test_end_step(3);
207+ for (i = NUM_OBJECTS; i < (NUM_OBJECTS * 2); i++) {
208+ oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
214209
215- /* [6.2.4] Adding the objects to the pool using
216- chGuardedPoolFree().*/
217- test_set_step(4);
218- {
219- for (i = 0; i < MEMORY_POOL_SIZE; i++)
220- chGuardedPoolFree(&gmp1, &objects[i]);
221- }
222- test_end_step(4);
210+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
211+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) == 0U, "not in sync");
223212
224- /* [6.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
225- again.*/
226- test_set_step(5);
227- {
228- for (i = 0; i < MEMORY_POOL_SIZE; i++)
229- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
213+ chCacheReleaseObject(&cache1, objp);
214+ }
215+
216+ test_assert_sequence("", "unexpected tokens");
230217 }
231218 test_end_step(5);
232219
233- /* [6.2.6] Now must be empty again.*/
220+ /* [6.1.6] Checking non-cached objects.*/
234221 test_set_step(6);
235222 {
236- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
237- }
238- test_end_step(6);
239-}
223+ uint32_t i;
240224
241-static const testcase_t oslib_test_006_002 = {
242- "Loading and emptying a guarded memory pool without waiting",
243- oslib_test_006_002_setup,
244- NULL,
245- oslib_test_006_002_execute
246-};
247-#endif /* CH_CFG_USE_SEMAPHORES */
225+ for (i = 0; i < NUM_OBJECTS; i++) {
226+ oc_object_t *objp = chCacheGetObject(&cache1, 0U, i);
248227
249-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
250-/**
251- * @page oslib_test_006_003 [6.3] Guarded Memory Pools timeout
252- *
253- * <h2>Description</h2>
254- * The timeout features for the Guarded Memory Pools is tested.
255- *
256- * <h2>Conditions</h2>
257- * This test is only executed if the following preprocessor condition
258- * evaluates to true:
259- * - CH_CFG_USE_SEMAPHORES
260- * .
261- *
262- * <h2>Test Steps</h2>
263- * - [6.3.1] Trying to allocate with 100mS timeout, must fail because
264- * the pool is empty.
265- * .
266- */
228+ test_assert((objp->obj_flags & OC_FLAG_INHASH) != 0U, "not in hash");
229+ test_assert((objp->obj_flags & OC_FLAG_NOTSYNC) != 0U, "in sync");
267230
268-static void oslib_test_006_003_setup(void) {
269- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
270-}
231+ chCacheReleaseObject(&cache1, objp);
232+ }
271233
272-static void oslib_test_006_003_execute(void) {
273-
274- /* [6.3.1] Trying to allocate with 100mS timeout, must fail because
275- the pool is empty.*/
276- test_set_step(1);
277- {
278- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
234+ test_assert_sequence("", "unexpected tokens");
279235 }
280- test_end_step(1);
236+ test_end_step(6);
281237 }
282238
283-static const testcase_t oslib_test_006_003 = {
284- "Guarded Memory Pools timeout",
285- oslib_test_006_003_setup,
239+static const testcase_t oslib_test_006_001 = {
240+ "Cache initialization",
286241 NULL,
287- oslib_test_006_003_execute
242+ NULL,
243+ oslib_test_006_001_execute
288244 };
289-#endif /* CH_CFG_USE_SEMAPHORES */
290245
291246 /****************************************************************************
292247 * Exported data.
@@ -297,21 +252,15 @@
297252 */
298253 const testcase_t * const oslib_test_sequence_006_array[] = {
299254 &oslib_test_006_001,
300-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
301- &oslib_test_006_002,
302-#endif
303-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
304- &oslib_test_006_003,
305-#endif
306255 NULL
307256 };
308257
309258 /**
310- * @brief Memory Pools.
259+ * @brief Objects Caches.
311260 */
312261 const testsequence_t oslib_test_sequence_006 = {
313- "Memory Pools",
262+ "Objects Caches",
314263 oslib_test_sequence_006_array
315264 };
316265
317-#endif /* CH_CFG_USE_MEMPOOLS */
266+#endif /* CH_CFG_USE_OBJ_CACHES */
--- trunk/test/oslib/source/test/oslib_test_sequence_007.c (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_sequence_007.c (revision 13204)
@@ -21,253 +21,273 @@
2121 * @file oslib_test_sequence_007.c
2222 * @brief Test Sequence 007 code.
2323 *
24- * @page oslib_test_sequence_007 [7] Memory Heaps
24+ * @page oslib_test_sequence_007 [7] Memory Pools
2525 *
2626 * File: @ref oslib_test_sequence_007.c
2727 *
2828 * <h2>Description</h2>
2929 * This sequence tests the ChibiOS library functionalities related to
30- * memory heaps.
30+ * memory pools.
3131 *
3232 * <h2>Conditions</h2>
3333 * This sequence is only executed if the following preprocessor condition
3434 * evaluates to true:
35- * - CH_CFG_USE_HEAP
35+ * - CH_CFG_USE_MEMPOOLS
3636 * .
3737 *
3838 * <h2>Test Cases</h2>
3939 * - @subpage oslib_test_007_001
4040 * - @subpage oslib_test_007_002
41+ * - @subpage oslib_test_007_003
4142 * .
4243 */
4344
44-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
45+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
4546
4647 /****************************************************************************
4748 * Shared code.
4849 ****************************************************************************/
4950
50-#define ALLOC_SIZE 16
51-#define HEAP_SIZE (ALLOC_SIZE * 8)
51+#define MEMORY_POOL_SIZE 4
5252
53-static memory_heap_t test_heap;
54-static uint8_t test_heap_buffer[HEAP_SIZE];
53+static uint32_t objects[MEMORY_POOL_SIZE];
54+static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
5555
56+#if CH_CFG_USE_SEMAPHORES
57+static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
58+#endif
59+
60+static void *null_provider(size_t size, unsigned align) {
61+
62+ (void)size;
63+ (void)align;
64+
65+ return NULL;
66+}
67+
5668 /****************************************************************************
5769 * Test cases.
5870 ****************************************************************************/
5971
6072 /**
61- * @page oslib_test_007_001 [7.1] Allocation and fragmentation
73+ * @page oslib_test_007_001 [7.1] Loading and emptying a memory pool
6274 *
6375 * <h2>Description</h2>
64- * Series of allocations/deallocations are performed in carefully
65- * designed sequences in order to stimulate all the possible code paths
66- * inside the allocator. The test expects to find the heap back to the
67- * initial status after each sequence.
76+ * The memory pool functionality is tested by loading and emptying it,
77+ * all conditions are tested.
6878 *
6979 * <h2>Test Steps</h2>
70- * - [7.1.1] Testing initial conditions, the heap must not be
71- * fragmented and one free block present.
72- * - [7.1.2] Trying to allocate an block bigger than available space,
73- * an error is expected.
74- * - [7.1.3] Single block allocation using chHeapAlloc() then the block
75- * is freed using chHeapFree(), must not fail.
76- * - [7.1.4] Using chHeapStatus() to assess the heap state. There must
77- * be at least one free block of sufficient size.
78- * - [7.1.5] Allocating then freeing in the same order.
79- * - [7.1.6] Allocating then freeing in reverse order.
80- * - [7.1.7] Small fragments handling. Checking the behavior when
81- * allocating blocks with size not multiple of alignment unit.
82- * - [7.1.8] Skipping a fragment, the first fragment in the list is too
83- * small so the allocator must pick the second one.
84- * - [7.1.9] Allocating the whole available space.
85- * - [7.1.10] Testing final conditions. The heap geometry must be the
86- * same than the one registered at beginning.
80+ * - [7.1.1] Adding the objects to the pool using chPoolLoadArray().
81+ * - [7.1.2] Emptying the pool using chPoolAlloc().
82+ * - [7.1.3] Now must be empty.
83+ * - [7.1.4] Adding the objects to the pool using chPoolFree().
84+ * - [7.1.5] Emptying the pool using chPoolAlloc() again.
85+ * - [7.1.6] Now must be empty again.
86+ * - [7.1.7] Covering the case where a provider is unable to return
87+ * more memory.
8788 * .
8889 */
8990
9091 static void oslib_test_007_001_setup(void) {
91- chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
92+ chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
9293 }
9394
9495 static void oslib_test_007_001_execute(void) {
95- void *p1, *p2, *p3;
96- size_t n, sz;
96+ unsigned i;
9797
98- /* [7.1.1] Testing initial conditions, the heap must not be
99- fragmented and one free block present.*/
98+ /* [7.1.1] Adding the objects to the pool using chPoolLoadArray().*/
10099 test_set_step(1);
101100 {
102- test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
101+ chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
103102 }
104103 test_end_step(1);
105104
106- /* [7.1.2] Trying to allocate an block bigger than available space,
107- an error is expected.*/
105+ /* [7.1.2] Emptying the pool using chPoolAlloc().*/
108106 test_set_step(2);
109107 {
110- p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
111- test_assert(p1 == NULL, "allocation not failed");
108+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
109+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
112110 }
113111 test_end_step(2);
114112
115- /* [7.1.3] Single block allocation using chHeapAlloc() then the block
116- is freed using chHeapFree(), must not fail.*/
113+ /* [7.1.3] Now must be empty.*/
117114 test_set_step(3);
118115 {
119- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
120- test_assert(p1 != NULL, "allocation failed");
121- chHeapFree(p1);
116+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
122117 }
123118 test_end_step(3);
124119
125- /* [7.1.4] Using chHeapStatus() to assess the heap state. There must
126- be at least one free block of sufficient size.*/
120+ /* [7.1.4] Adding the objects to the pool using chPoolFree().*/
127121 test_set_step(4);
128122 {
129- size_t total_size, largest_size;
130-
131- n = chHeapStatus(&test_heap, &total_size, &largest_size);
132- test_assert(n == 1, "missing free block");
133- test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
134- test_assert(total_size == largest_size, "unexpected heap state");
123+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
124+ chPoolFree(&mp1, &objects[i]);
135125 }
136126 test_end_step(4);
137127
138- /* [7.1.5] Allocating then freeing in the same order.*/
128+ /* [7.1.5] Emptying the pool using chPoolAlloc() again.*/
139129 test_set_step(5);
140130 {
141- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
142- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
143- p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
144- chHeapFree(p1); /* Does not merge.*/
145- chHeapFree(p2); /* Merges backward.*/
146- chHeapFree(p3); /* Merges both sides.*/
147- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
131+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
132+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
148133 }
149134 test_end_step(5);
150135
151- /* [7.1.6] Allocating then freeing in reverse order.*/
136+ /* [7.1.6] Now must be empty again.*/
152137 test_set_step(6);
153138 {
154- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
155- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
156- p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
157- chHeapFree(p3); /* Merges forward.*/
158- chHeapFree(p2); /* Merges forward.*/
159- chHeapFree(p1); /* Merges forward.*/
160- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
139+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
161140 }
162141 test_end_step(6);
163142
164- /* [7.1.7] Small fragments handling. Checking the behavior when
165- allocating blocks with size not multiple of alignment unit.*/
143+ /* [7.1.7] Covering the case where a provider is unable to return
144+ more memory.*/
166145 test_set_step(7);
167146 {
168- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
169- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
170- chHeapFree(p1);
171- test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
172- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
173- /* Note, the first situation happens when the alignment size is smaller
174- than the header size, the second in the other cases.*/
175- test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
176- (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
177- chHeapFree(p2);
178- chHeapFree(p1);
179- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
147+ chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
148+ test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
180149 }
181150 test_end_step(7);
182-
183- /* [7.1.8] Skipping a fragment, the first fragment in the list is too
184- small so the allocator must pick the second one.*/
185- test_set_step(8);
186- {
187- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
188- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
189- chHeapFree(p1);
190- test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
191- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
192- chHeapFree(p1);
193- chHeapFree(p2);
194- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
195- }
196- test_end_step(8);
197-
198- /* [7.1.9] Allocating the whole available space.*/
199- test_set_step(9);
200- {
201- (void)chHeapStatus(&test_heap, &n, NULL);
202- p1 = chHeapAlloc(&test_heap, n);
203- test_assert(p1 != NULL, "allocation failed");
204- test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
205- chHeapFree(p1);
206- }
207- test_end_step(9);
208-
209- /* [7.1.10] Testing final conditions. The heap geometry must be the
210- same than the one registered at beginning.*/
211- test_set_step(10);
212- {
213- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
214- test_assert(n == sz, "size changed");
215- }
216- test_end_step(10);
217151 }
218152
219153 static const testcase_t oslib_test_007_001 = {
220- "Allocation and fragmentation",
154+ "Loading and emptying a memory pool",
221155 oslib_test_007_001_setup,
222156 NULL,
223157 oslib_test_007_001_execute
224158 };
225159
160+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
226161 /**
227- * @page oslib_test_007_002 [7.2] Default Heap
162+ * @page oslib_test_007_002 [7.2] Loading and emptying a guarded memory pool without waiting
228163 *
229164 * <h2>Description</h2>
230- * The default heap is pre-allocated in the system. We test base
231- * functionality.
165+ * The memory pool functionality is tested by loading and emptying it,
166+ * all conditions are tested.
232167 *
168+ * <h2>Conditions</h2>
169+ * This test is only executed if the following preprocessor condition
170+ * evaluates to true:
171+ * - CH_CFG_USE_SEMAPHORES
172+ * .
173+ *
233174 * <h2>Test Steps</h2>
234- * - [7.2.1] Single block allocation using chHeapAlloc() then the block
235- * is freed using chHeapFree(), must not fail.
236- * - [7.2.2] Testing allocation failure.
175+ * - [7.2.1] Adding the objects to the pool using
176+ * chGuardedPoolLoadArray().
177+ * - [7.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
178+ * - [7.2.3] Now must be empty.
179+ * - [7.2.4] Adding the objects to the pool using chGuardedPoolFree().
180+ * - [7.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
181+ * - [7.2.6] Now must be empty again.
237182 * .
238183 */
239184
185+static void oslib_test_007_002_setup(void) {
186+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
187+}
188+
240189 static void oslib_test_007_002_execute(void) {
241- void *p1;
242- size_t total_size, largest_size;
190+ unsigned i;
243191
244- /* [7.2.1] Single block allocation using chHeapAlloc() then the block
245- is freed using chHeapFree(), must not fail.*/
192+ /* [7.2.1] Adding the objects to the pool using
193+ chGuardedPoolLoadArray().*/
246194 test_set_step(1);
247195 {
248- (void)chHeapStatus(NULL, &total_size, &largest_size);
249- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
250- test_assert(p1 != NULL, "allocation failed");
251- chHeapFree(p1);
196+ chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
252197 }
253198 test_end_step(1);
254199
255- /* [7.2.2] Testing allocation failure.*/
200+ /* [7.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
256201 test_set_step(2);
257202 {
258- p1 = chHeapAlloc(NULL, (size_t)-256);
259- test_assert(p1 == NULL, "allocation not failed");
203+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
204+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
260205 }
261206 test_end_step(2);
207+
208+ /* [7.2.3] Now must be empty.*/
209+ test_set_step(3);
210+ {
211+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
212+ }
213+ test_end_step(3);
214+
215+ /* [7.2.4] Adding the objects to the pool using
216+ chGuardedPoolFree().*/
217+ test_set_step(4);
218+ {
219+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
220+ chGuardedPoolFree(&gmp1, &objects[i]);
221+ }
222+ test_end_step(4);
223+
224+ /* [7.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
225+ again.*/
226+ test_set_step(5);
227+ {
228+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
229+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
230+ }
231+ test_end_step(5);
232+
233+ /* [7.2.6] Now must be empty again.*/
234+ test_set_step(6);
235+ {
236+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
237+ }
238+ test_end_step(6);
262239 }
263240
264241 static const testcase_t oslib_test_007_002 = {
265- "Default Heap",
242+ "Loading and emptying a guarded memory pool without waiting",
243+ oslib_test_007_002_setup,
266244 NULL,
267- NULL,
268245 oslib_test_007_002_execute
269246 };
247+#endif /* CH_CFG_USE_SEMAPHORES */
270248
249+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
250+/**
251+ * @page oslib_test_007_003 [7.3] Guarded Memory Pools timeout
252+ *
253+ * <h2>Description</h2>
254+ * The timeout features for the Guarded Memory Pools is tested.
255+ *
256+ * <h2>Conditions</h2>
257+ * This test is only executed if the following preprocessor condition
258+ * evaluates to true:
259+ * - CH_CFG_USE_SEMAPHORES
260+ * .
261+ *
262+ * <h2>Test Steps</h2>
263+ * - [7.3.1] Trying to allocate with 100mS timeout, must fail because
264+ * the pool is empty.
265+ * .
266+ */
267+
268+static void oslib_test_007_003_setup(void) {
269+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
270+}
271+
272+static void oslib_test_007_003_execute(void) {
273+
274+ /* [7.3.1] Trying to allocate with 100mS timeout, must fail because
275+ the pool is empty.*/
276+ test_set_step(1);
277+ {
278+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
279+ }
280+ test_end_step(1);
281+}
282+
283+static const testcase_t oslib_test_007_003 = {
284+ "Guarded Memory Pools timeout",
285+ oslib_test_007_003_setup,
286+ NULL,
287+ oslib_test_007_003_execute
288+};
289+#endif /* CH_CFG_USE_SEMAPHORES */
290+
271291 /****************************************************************************
272292 * Exported data.
273293 ****************************************************************************/
@@ -277,16 +297,21 @@
277297 */
278298 const testcase_t * const oslib_test_sequence_007_array[] = {
279299 &oslib_test_007_001,
300+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
280301 &oslib_test_007_002,
302+#endif
303+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
304+ &oslib_test_007_003,
305+#endif
281306 NULL
282307 };
283308
284309 /**
285- * @brief Memory Heaps.
310+ * @brief Memory Pools.
286311 */
287312 const testsequence_t oslib_test_sequence_007 = {
288- "Memory Heaps",
313+ "Memory Pools",
289314 oslib_test_sequence_007_array
290315 };
291316
292-#endif /* CH_CFG_USE_HEAP */
317+#endif /* CH_CFG_USE_MEMPOOLS */
--- trunk/test/oslib/source/test/oslib_test_sequence_008.c (revision 13203)
+++ trunk/test/oslib/source/test/oslib_test_sequence_008.c (revision 13204)
@@ -21,762 +21,253 @@
2121 * @file oslib_test_sequence_008.c
2222 * @brief Test Sequence 008 code.
2323 *
24- * @page oslib_test_sequence_008 [8] Objects Factory
24+ * @page oslib_test_sequence_008 [8] Memory Heaps
2525 *
2626 * File: @ref oslib_test_sequence_008.c
2727 *
2828 * <h2>Description</h2>
2929 * This sequence tests the ChibiOS library functionalities related to
30- * the object factory.
30+ * memory heaps.
3131 *
3232 * <h2>Conditions</h2>
3333 * This sequence is only executed if the following preprocessor condition
3434 * evaluates to true:
35- * - (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)
35+ * - CH_CFG_USE_HEAP
3636 * .
3737 *
3838 * <h2>Test Cases</h2>
3939 * - @subpage oslib_test_008_001
4040 * - @subpage oslib_test_008_002
41- * - @subpage oslib_test_008_003
42- * - @subpage oslib_test_008_004
43- * - @subpage oslib_test_008_005
44- * - @subpage oslib_test_008_006
4541 * .
4642 */
4743
48-#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
44+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
4945
5046 /****************************************************************************
5147 * Shared code.
5248 ****************************************************************************/
5349
50+#define ALLOC_SIZE 16
51+#define HEAP_SIZE (ALLOC_SIZE * 8)
5452
53+static memory_heap_t test_heap;
54+static uint8_t test_heap_buffer[HEAP_SIZE];
55+
5556 /****************************************************************************
5657 * Test cases.
5758 ****************************************************************************/
5859
59-#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
6060 /**
61- * @page oslib_test_008_001 [8.1] Objects Registry
61+ * @page oslib_test_008_001 [8.1] Allocation and fragmentation
6262 *
6363 * <h2>Description</h2>
64- * This test case verifies the static objects registry.
64+ * Series of allocations/deallocations are performed in carefully
65+ * designed sequences in order to stimulate all the possible code paths
66+ * inside the allocator. The test expects to find the heap back to the
67+ * initial status after each sequence.
6568 *
66- * <h2>Conditions</h2>
67- * This test is only executed if the following preprocessor condition
68- * evaluates to true:
69- * - CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
70- * .
71- *
7269 * <h2>Test Steps</h2>
73- * - [8.1.1] Retrieving a registered object by name, must not exist.
74- * - [8.1.2] Registering an object, it must not exists, must succeed.
75- * - [8.1.3] Registering an object with the same name, must fail.
76- * - [8.1.4] Retrieving the registered object by name, must exist, then
77- * increasing the reference counter, finally releasing both
78- * references.
79- * - [8.1.5] Releasing the first reference to the object, must not
80- * trigger an assertion.
81- * - [8.1.6] Retrieving the registered object by name again, must not
82- * exist.
70+ * - [8.1.1] Testing initial conditions, the heap must not be
71+ * fragmented and one free block present.
72+ * - [8.1.2] Trying to allocate an block bigger than available space,
73+ * an error is expected.
74+ * - [8.1.3] Single block allocation using chHeapAlloc() then the block
75+ * is freed using chHeapFree(), must not fail.
76+ * - [8.1.4] Using chHeapStatus() to assess the heap state. There must
77+ * be at least one free block of sufficient size.
78+ * - [8.1.5] Allocating then freeing in the same order.
79+ * - [8.1.6] Allocating then freeing in reverse order.
80+ * - [8.1.7] Small fragments handling. Checking the behavior when
81+ * allocating blocks with size not multiple of alignment unit.
82+ * - [8.1.8] Skipping a fragment, the first fragment in the list is too
83+ * small so the allocator must pick the second one.
84+ * - [8.1.9] Allocating the whole available space.
85+ * - [8.1.10] Testing final conditions. The heap geometry must be the
86+ * same than the one registered at beginning.
8387 * .
8488 */
8589
86-static void oslib_test_008_001_teardown(void) {
87- registered_object_t *rop;
88-
89- rop = chFactoryFindObject("myobj");
90- if (rop != NULL) {
91- while (rop->element.refs > 0U) {
92- chFactoryReleaseObject(rop);
93- }
94- }
90+static void oslib_test_008_001_setup(void) {
91+ chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
9592 }
9693
9794 static void oslib_test_008_001_execute(void) {
98- registered_object_t *rop;
95+ void *p1, *p2, *p3;
96+ size_t n, sz;
9997
100- /* [8.1.1] Retrieving a registered object by name, must not exist.*/
98+ /* [8.1.1] Testing initial conditions, the heap must not be
99+ fragmented and one free block present.*/
101100 test_set_step(1);
102101 {
103- rop = chFactoryFindObject("myobj");
104- test_assert(rop == NULL, "found");
102+ test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
105103 }
106104 test_end_step(1);
107105
108- /* [8.1.2] Registering an object, it must not exists, must succeed.*/
106+ /* [8.1.2] Trying to allocate an block bigger than available space,
107+ an error is expected.*/
109108 test_set_step(2);
110109 {
111- static uint32_t myobj = 0x55aa;
112-
113- rop = chFactoryRegisterObject("myobj", (void *)&myobj);
114- test_assert(rop != NULL, "cannot register");
110+ p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
111+ test_assert(p1 == NULL, "allocation not failed");
115112 }
116113 test_end_step(2);
117114
118- /* [8.1.3] Registering an object with the same name, must fail.*/
115+ /* [8.1.3] Single block allocation using chHeapAlloc() then the block
116+ is freed using chHeapFree(), must not fail.*/
119117 test_set_step(3);
120118 {
121- registered_object_t *rop1;
122- static uint32_t myobj = 0x55aa;
123-
124- rop1 = chFactoryRegisterObject("myobj", (void *)&myobj);
125- test_assert(rop1 == NULL, "can register");
119+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
120+ test_assert(p1 != NULL, "allocation failed");
121+ chHeapFree(p1);
126122 }
127123 test_end_step(3);
128124
129- /* [8.1.4] Retrieving the registered object by name, must exist, then
130- increasing the reference counter, finally releasing both
131- references.*/
125+ /* [8.1.4] Using chHeapStatus() to assess the heap state. There must
126+ be at least one free block of sufficient size.*/
132127 test_set_step(4);
133128 {
134- registered_object_t *rop1, *rop2;
129+ size_t total_size, largest_size;
135130
136- rop1 = chFactoryFindObject("myobj");
137- test_assert(rop1 != NULL, "not found");
138- test_assert(*(uint32_t *)(rop1->objp) == 0x55aa, "object mismatch");
139- test_assert(rop == rop1, "object reference mismatch");
140- test_assert(rop1->element.refs == 2, "object reference mismatch");
141-
142- rop2 = (registered_object_t *)chFactoryDuplicateReference(&rop1->element);
143- test_assert(rop1 == rop2, "object reference mismatch");
144- test_assert(*(uint32_t *)(rop2->objp) == 0x55aa, "object mismatch");
145- test_assert(rop2->element.refs == 3, "object reference mismatch");
146-
147- chFactoryReleaseObject(rop2);
148- test_assert(rop1->element.refs == 2, "references mismatch");
149-
150- chFactoryReleaseObject(rop1);
151- test_assert(rop->element.refs == 1, "references mismatch");
131+ n = chHeapStatus(&test_heap, &total_size, &largest_size);
132+ test_assert(n == 1, "missing free block");
133+ test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
134+ test_assert(total_size == largest_size, "unexpected heap state");
152135 }
153136 test_end_step(4);
154137
155- /* [8.1.5] Releasing the first reference to the object, must not
156- trigger an assertion.*/
138+ /* [8.1.5] Allocating then freeing in the same order.*/
157139 test_set_step(5);
158140 {
159- chFactoryReleaseObject(rop);
141+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
142+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
143+ p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
144+ chHeapFree(p1); /* Does not merge.*/
145+ chHeapFree(p2); /* Merges backward.*/
146+ chHeapFree(p3); /* Merges both sides.*/
147+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
160148 }
161149 test_end_step(5);
162150
163- /* [8.1.6] Retrieving the registered object by name again, must not
164- exist.*/
151+ /* [8.1.6] Allocating then freeing in reverse order.*/
165152 test_set_step(6);
166153 {
167- rop = chFactoryFindObject("myobj");
168- test_assert(rop == NULL, "found");
154+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
155+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
156+ p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
157+ chHeapFree(p3); /* Merges forward.*/
158+ chHeapFree(p2); /* Merges forward.*/
159+ chHeapFree(p1); /* Merges forward.*/
160+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
169161 }
170162 test_end_step(6);
171-}
172163
173-static const testcase_t oslib_test_008_001 = {
174- "Objects Registry",
175- NULL,
176- oslib_test_008_001_teardown,
177- oslib_test_008_001_execute
178-};
179-#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
180-
181-#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
182-/**
183- * @page oslib_test_008_002 [8.2] Dynamic Buffers Factory
184- *
185- * <h2>Description</h2>
186- * This test case verifies the dynamic buffers factory.
187- *
188- * <h2>Conditions</h2>
189- * This test is only executed if the following preprocessor condition
190- * evaluates to true:
191- * - CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
192- * .
193- *
194- * <h2>Test Steps</h2>
195- * - [8.2.1] Retrieving a dynamic buffer by name, must not exist.
196- * - [8.2.2] Creating a dynamic buffer it must not exists, must
197- * succeed.
198- * - [8.2.3] Creating a dynamic buffer with the same name, must fail.
199- * - [8.2.4] Retrieving the dynamic buffer by name, must exist, then
200- * increasing the reference counter, finally releasing both
201- * references.
202- * - [8.2.5] Releasing the first reference to the dynamic buffer, must
203- * not trigger an assertion.
204- * - [8.2.6] Retrieving the dynamic buffer by name again, must not
205- * exist.
206- * .
207- */
208-
209-static void oslib_test_008_002_teardown(void) {
210- dyn_buffer_t *dbp;
211-
212- dbp = chFactoryFindBuffer("mybuf");
213- if (dbp != NULL) {
214- while (dbp->element.refs > 0U) {
215- chFactoryReleaseBuffer(dbp);
216- }
217- }
218-}
219-
220-static void oslib_test_008_002_execute(void) {
221- dyn_buffer_t *dbp;
222-
223- /* [8.2.1] Retrieving a dynamic buffer by name, must not exist.*/
224- test_set_step(1);
164+ /* [8.1.7] Small fragments handling. Checking the behavior when
165+ allocating blocks with size not multiple of alignment unit.*/
166+ test_set_step(7);
225167 {
226- dbp = chFactoryFindBuffer("mybuf");
227- test_assert(dbp == NULL, "found");
168+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
169+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
170+ chHeapFree(p1);
171+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
172+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
173+ /* Note, the first situation happens when the alignment size is smaller
174+ than the header size, the second in the other cases.*/
175+ test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
176+ (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
177+ chHeapFree(p2);
178+ chHeapFree(p1);
179+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
228180 }
229- test_end_step(1);
181+ test_end_step(7);
230182
231- /* [8.2.2] Creating a dynamic buffer it must not exists, must
232- succeed.*/
233- test_set_step(2);
183+ /* [8.1.8] Skipping a fragment, the first fragment in the list is too
184+ small so the allocator must pick the second one.*/
185+ test_set_step(8);
234186 {
235- dbp = chFactoryCreateBuffer("mybuf", 128U);
236- test_assert(dbp != NULL, "cannot create");
187+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
188+ p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
189+ chHeapFree(p1);
190+ test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
191+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
192+ chHeapFree(p1);
193+ chHeapFree(p2);
194+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
237195 }
238- test_end_step(2);
196+ test_end_step(8);
239197
240- /* [8.2.3] Creating a dynamic buffer with the same name, must fail.*/
241- test_set_step(3);
198+ /* [8.1.9] Allocating the whole available space.*/
199+ test_set_step(9);
242200 {
243- dyn_buffer_t *dbp1;
244-
245- dbp1 = chFactoryCreateBuffer("mybuf", 128U);
246- test_assert(dbp1 == NULL, "can create");
201+ (void)chHeapStatus(&test_heap, &n, NULL);
202+ p1 = chHeapAlloc(&test_heap, n);
203+ test_assert(p1 != NULL, "allocation failed");
204+ test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
205+ chHeapFree(p1);
247206 }
248- test_end_step(3);
207+ test_end_step(9);
249208
250- /* [8.2.4] Retrieving the dynamic buffer by name, must exist, then
251- increasing the reference counter, finally releasing both
252- references.*/
253- test_set_step(4);
209+ /* [8.1.10] Testing final conditions. The heap geometry must be the
210+ same than the one registered at beginning.*/
211+ test_set_step(10);
254212 {
255- dyn_buffer_t *dbp1, *dbp2;
256-
257- dbp1 = chFactoryFindBuffer("mybuf");
258- test_assert(dbp1 != NULL, "not found");
259- test_assert(dbp == dbp1, "object reference mismatch");
260- test_assert(dbp1->element.refs == 2, "object reference mismatch");
261-
262- dbp2 = (dyn_buffer_t *)chFactoryDuplicateReference(&dbp1->element);
263- test_assert(dbp1 == dbp2, "object reference mismatch");
264- test_assert(dbp2->element.refs == 3, "object reference mismatch");
265-
266- chFactoryReleaseBuffer(dbp2);
267- test_assert(dbp1->element.refs == 2, "references mismatch");
268-
269- chFactoryReleaseBuffer(dbp1);
270- test_assert(dbp->element.refs == 1, "references mismatch");
213+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
214+ test_assert(n == sz, "size changed");
271215 }
272- test_end_step(4);
273-
274- /* [8.2.5] Releasing the first reference to the dynamic buffer, must
275- not trigger an assertion.*/
276- test_set_step(5);
277- {
278- chFactoryReleaseBuffer(dbp);
279- }
280- test_end_step(5);
281-
282- /* [8.2.6] Retrieving the dynamic buffer by name again, must not
283- exist.*/
284- test_set_step(6);
285- {
286- dbp = chFactoryFindBuffer("mybuf");
287- test_assert(dbp == NULL, "found");
288- }
289- test_end_step(6);
216+ test_end_step(10);
290217 }
291218
292-static const testcase_t oslib_test_008_002 = {
293- "Dynamic Buffers Factory",
219+static const testcase_t oslib_test_008_001 = {
220+ "Allocation and fragmentation",
221+ oslib_test_008_001_setup,
294222 NULL,
295- oslib_test_008_002_teardown,
296- oslib_test_008_002_execute
223+ oslib_test_008_001_execute
297224 };
298-#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
299225
300-#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
301226 /**
302- * @page oslib_test_008_003 [8.3] Dynamic Semaphores Factory
227+ * @page oslib_test_008_002 [8.2] Default Heap
303228 *
304229 * <h2>Description</h2>
305- * This test case verifies the dynamic semaphores factory.
230+ * The default heap is pre-allocated in the system. We test base
231+ * functionality.
306232 *
307- * <h2>Conditions</h2>
308- * This test is only executed if the following preprocessor condition
309- * evaluates to true:
310- * - CH_CFG_FACTORY_SEMAPHORES == TRUE
311- * .
312- *
313233 * <h2>Test Steps</h2>
314- * - [8.3.1] Retrieving a dynamic semaphore by name, must not exist.
315- * - [8.3.2] Creating a dynamic semaphore it must not exists, must
316- * succeed.
317- * - [8.3.3] Creating a dynamic semaphore with the same name, must
318- * fail.
319- * - [8.3.4] Retrieving the dynamic semaphore by name, must exist, then
320- * increasing the reference counter, finally releasing both
321- * references.
322- * - [8.3.5] Releasing the first reference to the dynamic semaphore
323- * must not trigger an assertion.
324- * - [8.3.6] Retrieving the dynamic semaphore by name again, must not
325- * exist.
234+ * - [8.2.1] Single block allocation using chHeapAlloc() then the block
235+ * is freed using chHeapFree(), must not fail.
236+ * - [8.2.2] Testing allocation failure.
326237 * .
327238 */
328239
329-static void oslib_test_008_003_teardown(void) {
330- dyn_semaphore_t *dsp;
240+static void oslib_test_008_002_execute(void) {
241+ void *p1;
242+ size_t total_size, largest_size;
331243
332- dsp = chFactoryFindSemaphore("mysem");
333- if (dsp != NULL) {
334- while (dsp->element.refs > 0U) {
335- chFactoryReleaseSemaphore(dsp);
336- }
337- }
338-}
339-
340-static void oslib_test_008_003_execute(void) {
341- dyn_semaphore_t *dsp;
342-
343- /* [8.3.1] Retrieving a dynamic semaphore by name, must not exist.*/
244+ /* [8.2.1] Single block allocation using chHeapAlloc() then the block
245+ is freed using chHeapFree(), must not fail.*/
344246 test_set_step(1);
345247 {
346- dsp = chFactoryFindSemaphore("mysem");
347- test_assert(dsp == NULL, "found");
248+ (void)chHeapStatus(NULL, &total_size, &largest_size);
249+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
250+ test_assert(p1 != NULL, "allocation failed");
251+ chHeapFree(p1);
348252 }
349253 test_end_step(1);
350254
351- /* [8.3.2] Creating a dynamic semaphore it must not exists, must
352- succeed.*/
255+ /* [8.2.2] Testing allocation failure.*/
353256 test_set_step(2);
354257 {
355- dsp = chFactoryCreateSemaphore("mysem", 0);
356- test_assert(dsp != NULL, "cannot create");
258+ p1 = chHeapAlloc(NULL, (size_t)-256);
259+ test_assert(p1 == NULL, "allocation not failed");
357260 }
358261 test_end_step(2);
359-
360- /* [8.3.3] Creating a dynamic semaphore with the same name, must
361- fail.*/
362- test_set_step(3);
363- {
364- dyn_semaphore_t *dsp1;
365-
366- dsp1 = chFactoryCreateSemaphore("mysem", 0);
367- test_assert(dsp1 == NULL, "can create");
368- }
369- test_end_step(3);
370-
371- /* [8.3.4] Retrieving the dynamic semaphore by name, must exist, then
372- increasing the reference counter, finally releasing both
373- references.*/
374- test_set_step(4);
375- {
376- dyn_semaphore_t *dsp1, *dsp2;
377-
378- dsp1 = chFactoryFindSemaphore("mysem");
379- test_assert(dsp1 != NULL, "not found");
380- test_assert(dsp == dsp1, "object reference mismatch");
381- test_assert(dsp1->element.refs == 2, "object reference mismatch");
382-
383- dsp2 = (dyn_semaphore_t *)chFactoryDuplicateReference(&dsp1->element);
384- test_assert(dsp1 == dsp2, "object reference mismatch");
385- test_assert(dsp2->element.refs == 3, "object reference mismatch");
386-
387- chFactoryReleaseSemaphore(dsp2);
388- test_assert(dsp1->element.refs == 2, "references mismatch");
389-
390- chFactoryReleaseSemaphore(dsp1);
391- test_assert(dsp->element.refs == 1, "references mismatch");
392- }
393- test_end_step(4);
394-
395- /* [8.3.5] Releasing the first reference to the dynamic semaphore
396- must not trigger an assertion.*/
397- test_set_step(5);
398- {
399- chFactoryReleaseSemaphore(dsp);
400- }
401- test_end_step(5);
402-
403- /* [8.3.6] Retrieving the dynamic semaphore by name again, must not
404- exist.*/
405- test_set_step(6);
406- {
407- dsp = chFactoryFindSemaphore("mysem");
408- test_assert(dsp == NULL, "found");
409- }
410- test_end_step(6);
411262 }
412263
413-static const testcase_t oslib_test_008_003 = {
414- "Dynamic Semaphores Factory",
264+static const testcase_t oslib_test_008_002 = {
265+ "Default Heap",
415266 NULL,
416- oslib_test_008_003_teardown,
417- oslib_test_008_003_execute
418-};
419-#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
420-
421-#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
422-/**
423- * @page oslib_test_008_004 [8.4] Dynamic Mailboxes Factory
424- *
425- * <h2>Description</h2>
426- * This test case verifies the dynamic mailboxes factory.
427- *
428- * <h2>Conditions</h2>
429- * This test is only executed if the following preprocessor condition
430- * evaluates to true:
431- * - CH_CFG_FACTORY_MAILBOXES == TRUE
432- * .
433- *
434- * <h2>Test Steps</h2>
435- * - [8.4.1] Retrieving a dynamic mailbox by name, must not exist.
436- * - [8.4.2] Creating a dynamic mailbox it must not exists, must
437- * succeed.
438- * - [8.4.3] Creating a dynamic mailbox with the same name, must fail.
439- * - [8.4.4] Retrieving the dynamic mailbox by name, must exist, then
440- * increasing the reference counter, finally releasing both
441- * references.
442- * - [8.4.5] Releasing the first reference to the dynamic mailbox must
443- * not trigger an assertion.
444- * - [8.4.6] Retrieving the dynamic mailbox by name again, must not
445- * exist.
446- * .
447- */
448-
449-static void oslib_test_008_004_teardown(void) {
450- dyn_mailbox_t *dmp;
451-
452- dmp = chFactoryFindMailbox("mymbx");
453- if (dmp != NULL) {
454- while (dmp->element.refs > 0U) {
455- chFactoryReleaseMailbox(dmp);
456- }
457- }
458-}
459-
460-static void oslib_test_008_004_execute(void) {
461- dyn_mailbox_t *dmp;
462-
463- /* [8.4.1] Retrieving a dynamic mailbox by name, must not exist.*/
464- test_set_step(1);
465- {
466- dmp = chFactoryFindMailbox("mymbx");
467- test_assert(dmp == NULL, "found");
468- }
469- test_end_step(1);
470-
471- /* [8.4.2] Creating a dynamic mailbox it must not exists, must
472- succeed.*/
473- test_set_step(2);
474- {
475- dmp = chFactoryCreateMailbox("mymbx", 16U);
476- test_assert(dmp != NULL, "cannot create");
477- }
478- test_end_step(2);
479-
480- /* [8.4.3] Creating a dynamic mailbox with the same name, must
481- fail.*/
482- test_set_step(3);
483- {
484- dyn_mailbox_t *dmp1;
485-
486- dmp1 = chFactoryCreateMailbox("mymbx", 16U);
487- test_assert(dmp1 == NULL, "can create");
488- }
489- test_end_step(3);
490-
491- /* [8.4.4] Retrieving the dynamic mailbox by name, must exist, then
492- increasing the reference counter, finally releasing both
493- references.*/
494- test_set_step(4);
495- {
496- dyn_mailbox_t *dmp1, *dmp2;
497-
498- dmp1 = chFactoryFindMailbox("mymbx");
499- test_assert(dmp1 != NULL, "not found");
500- test_assert(dmp == dmp1, "object reference mismatch");
501- test_assert(dmp1->element.refs == 2, "object reference mismatch");
502-
503- dmp2 = (dyn_mailbox_t *)chFactoryDuplicateReference(&dmp1->element);
504- test_assert(dmp1 == dmp2, "object reference mismatch");
505- test_assert(dmp2->element.refs == 3, "object reference mismatch");
506-
507- chFactoryReleaseMailbox(dmp2);
508- test_assert(dmp1->element.refs == 2, "references mismatch");
509-
510- chFactoryReleaseMailbox(dmp1);
511- test_assert(dmp->element.refs == 1, "references mismatch");
512- }
513- test_end_step(4);
514-
515- /* [8.4.5] Releasing the first reference to the dynamic mailbox must
516- not trigger an assertion.*/
517- test_set_step(5);
518- {
519- chFactoryReleaseMailbox(dmp);
520- }
521- test_end_step(5);
522-
523- /* [8.4.6] Retrieving the dynamic mailbox by name again, must not
524- exist.*/
525- test_set_step(6);
526- {
527- dmp = chFactoryFindMailbox("mymbx");
528- test_assert(dmp == NULL, "found");
529- }
530- test_end_step(6);
531-}
532-
533-static const testcase_t oslib_test_008_004 = {
534- "Dynamic Mailboxes Factory",
535267 NULL,
536- oslib_test_008_004_teardown,
537- oslib_test_008_004_execute
268+ oslib_test_008_002_execute
538269 };
539-#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
540270
541-#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
542-/**
543- * @page oslib_test_008_005 [8.5] Dynamic Objects FIFOs Factory
544- *
545- * <h2>Description</h2>
546- * This test case verifies the dynamic objects FIFOs factory.
547- *
548- * <h2>Conditions</h2>
549- * This test is only executed if the following preprocessor condition
550- * evaluates to true:
551- * - CH_CFG_FACTORY_OBJ_FIFOS == TRUE
552- * .
553- *
554- * <h2>Test Steps</h2>
555- * - [8.5.1] Retrieving a dynamic objects FIFO by name, must not exist.
556- * - [8.5.2] Creating a dynamic objects FIFO it must not exists, must
557- * succeed.
558- * - [8.5.3] Creating a dynamic objects FIFO with the same name, must
559- * fail.
560- * - [8.5.4] Retrieving the dynamic objects FIFO by name, must exist,
561- * then increasing the reference counter, finally releasing both
562- * references.
563- * - [8.5.5] Releasing the first reference to the dynamic objects FIFO
564- * must not trigger an assertion.
565- * - [8.5.6] Retrieving the dynamic objects FIFO by name again, must
566- * not exist.
567- * .
568- */
569-
570-static void oslib_test_008_005_teardown(void) {
571- dyn_objects_fifo_t *dofp;
572-
573- dofp = chFactoryFindObjectsFIFO("myfifo");
574- if (dofp != NULL) {
575- while (dofp->element.refs > 0U) {
576- chFactoryReleaseObjectsFIFO(dofp);
577- }
578- }
579-}
580-
581-static void oslib_test_008_005_execute(void) {
582- dyn_objects_fifo_t *dofp;
583-
584- /* [8.5.1] Retrieving a dynamic objects FIFO by name, must not
585- exist.*/
586- test_set_step(1);
587- {
588- dofp = chFactoryFindObjectsFIFO("myfifo");
589- test_assert(dofp == NULL, "found");
590- }
591- test_end_step(1);
592-
593- /* [8.5.2] Creating a dynamic objects FIFO it must not exists, must
594- succeed.*/
595- test_set_step(2);
596- {
597- dofp = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
598- test_assert(dofp != NULL, "cannot create");
599- }
600- test_end_step(2);
601-
602- /* [8.5.3] Creating a dynamic objects FIFO with the same name, must
603- fail.*/
604- test_set_step(3);
605- {
606- dyn_objects_fifo_t *dofp1;
607-
608- dofp1 = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
609- test_assert(dofp1 == NULL, "can create");
610- }
611- test_end_step(3);
612-
613- /* [8.5.4] Retrieving the dynamic objects FIFO by name, must exist,
614- then increasing the reference counter, finally releasing both
615- references.*/
616- test_set_step(4);
617- {
618- dyn_objects_fifo_t *dofp1, *dofp2;
619-
620- dofp1 = chFactoryFindObjectsFIFO("myfifo");
621- test_assert(dofp1 != NULL, "not found");
622- test_assert(dofp == dofp1, "object reference mismatch");
623- test_assert(dofp1->element.refs == 2, "object reference mismatch");
624-
625- dofp2 = (dyn_objects_fifo_t *)chFactoryDuplicateReference(&dofp1->element);
626- test_assert(dofp1 == dofp2, "object reference mismatch");
627- test_assert(dofp2->element.refs == 3, "object reference mismatch");
628-
629- chFactoryReleaseObjectsFIFO(dofp2);
630- test_assert(dofp1->element.refs == 2, "references mismatch");
631-
632- chFactoryReleaseObjectsFIFO(dofp1);
633- test_assert(dofp->element.refs == 1, "references mismatch");
634- }
635- test_end_step(4);
636-
637- /* [8.5.5] Releasing the first reference to the dynamic objects FIFO
638- must not trigger an assertion.*/
639- test_set_step(5);
640- {
641- chFactoryReleaseObjectsFIFO(dofp);
642- }
643- test_end_step(5);
644-
645- /* [8.5.6] Retrieving the dynamic objects FIFO by name again, must
646- not exist.*/
647- test_set_step(6);
648- {
649- dofp = chFactoryFindObjectsFIFO("myfifo");
650- test_assert(dofp == NULL, "found");
651- }
652- test_end_step(6);
653-}
654-
655-static const testcase_t oslib_test_008_005 = {
656- "Dynamic Objects FIFOs Factory",
657- NULL,
658- oslib_test_008_005_teardown,
659- oslib_test_008_005_execute
660-};
661-#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
662-
663-#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
664-/**
665- * @page oslib_test_008_006 [8.6] Dynamic Pipes Factory
666- *
667- * <h2>Description</h2>
668- * This test case verifies the dynamic pipes factory.
669- *
670- * <h2>Conditions</h2>
671- * This test is only executed if the following preprocessor condition
672- * evaluates to true:
673- * - CH_CFG_FACTORY_PIPES == TRUE
674- * .
675- *
676- * <h2>Test Steps</h2>
677- * - [8.6.1] Retrieving a dynamic pipe by name, must not exist.
678- * - [8.6.2] Creating a dynamic pipe it must not exists, must succeed.
679- * - [8.6.3] Creating a dynamic pipe with the same name, must fail.
680- * - [8.6.4] Retrieving the dynamic pipe by name, must exist, then
681- * increasing the reference counter, finally releasing both
682- * references.
683- * - [8.6.5] Releasing the first reference to the dynamic pipe must not
684- * trigger an assertion.
685- * - [8.6.6] Retrieving the dynamic pipe by name again, must not exist.
686- * .
687- */
688-
689-static void oslib_test_008_006_teardown(void) {
690- dyn_pipe_t *dpp;
691-
692- dpp = chFactoryFindPipe("mypipe");
693- if (dpp != NULL) {
694- while (dpp->element.refs > 0U) {
695- chFactoryReleasePipe(dpp);
696- }
697- }
698-}
699-
700-static void oslib_test_008_006_execute(void) {
701- dyn_pipe_t *dpp;
702-
703- /* [8.6.1] Retrieving a dynamic pipe by name, must not exist.*/
704- test_set_step(1);
705- {
706- dpp = chFactoryFindPipe("mypipe");
707- test_assert(dpp == NULL, "found");
708- }
709- test_end_step(1);
710-
711- /* [8.6.2] Creating a dynamic pipe it must not exists, must
712- succeed.*/
713- test_set_step(2);
714- {
715- dpp = chFactoryCreatePipe("mypipe", 16U);
716- test_assert(dpp != NULL, "cannot create");
717- }
718- test_end_step(2);
719-
720- /* [8.6.3] Creating a dynamic pipe with the same name, must fail.*/
721- test_set_step(3);
722- {
723- dyn_pipe_t *dpp1;
724-
725- dpp1 = chFactoryCreatePipe("mypipe", 16U);
726- test_assert(dpp1 == NULL, "can create");
727- }
728- test_end_step(3);
729-
730- /* [8.6.4] Retrieving the dynamic pipe by name, must exist, then
731- increasing the reference counter, finally releasing both
732- references.*/
733- test_set_step(4);
734- {
735- dyn_pipe_t *dpp1, *dpp2;
736-
737- dpp1 = chFactoryFindPipe("mypipe");
738- test_assert(dpp1 != NULL, "not found");
739- test_assert(dpp == dpp1, "object reference mismatch");
740- test_assert(dpp1->element.refs == 2, "object reference mismatch");
741-
742- dpp2 = (dyn_pipe_t *)chFactoryDuplicateReference(&dpp1->element);
743- test_assert(dpp1 == dpp2, "object reference mismatch");
744- test_assert(dpp2->element.refs == 3, "object reference mismatch");
745-
746- chFactoryReleasePipe(dpp2);
747- test_assert(dpp1->element.refs == 2, "references mismatch");
748-
749- chFactoryReleasePipe(dpp1);
750- test_assert(dpp->element.refs == 1, "references mismatch");
751- }
752- test_end_step(4);
753-
754- /* [8.6.5] Releasing the first reference to the dynamic pipe must not
755- trigger an assertion.*/
756- test_set_step(5);
757- {
758- chFactoryReleasePipe(dpp);
759- }
760- test_end_step(5);
761-
762- /* [8.6.6] Retrieving the dynamic pipe by name again, must not
763- exist.*/
764- test_set_step(6);
765- {
766- dpp = chFactoryFindPipe("mypipe");
767- test_assert(dpp == NULL, "found");
768- }
769- test_end_step(6);
770-}
771-
772-static const testcase_t oslib_test_008_006 = {
773- "Dynamic Pipes Factory",
774- NULL,
775- oslib_test_008_006_teardown,
776- oslib_test_008_006_execute
777-};
778-#endif /* CH_CFG_FACTORY_PIPES == TRUE */
779-
780271 /****************************************************************************
781272 * Exported data.
782273 ****************************************************************************/
@@ -785,33 +276,17 @@
785276 * @brief Array of test cases.
786277 */
787278 const testcase_t * const oslib_test_sequence_008_array[] = {
788-#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
789279 &oslib_test_008_001,
790-#endif
791-#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
792280 &oslib_test_008_002,
793-#endif
794-#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
795- &oslib_test_008_003,
796-#endif
797-#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
798- &oslib_test_008_004,
799-#endif
800-#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
801- &oslib_test_008_005,
802-#endif
803-#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
804- &oslib_test_008_006,
805-#endif
806281 NULL
807282 };
808283
809284 /**
810- * @brief Objects Factory.
285+ * @brief Memory Heaps.
811286 */
812287 const testsequence_t oslib_test_sequence_008 = {
813- "Objects Factory",
288+ "Memory Heaps",
814289 oslib_test_sequence_008_array
815290 };
816291
817-#endif /* (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) */
292+#endif /* CH_CFG_USE_HEAP */
--- trunk/test/oslib/source/test/oslib_test_sequence_009.c (nonexistent)
+++ trunk/test/oslib/source/test/oslib_test_sequence_009.c (revision 13204)
@@ -0,0 +1,817 @@
1+/*
2+ ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ http://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+*/
16+
17+#include "hal.h"
18+#include "oslib_test_root.h"
19+
20+/**
21+ * @file oslib_test_sequence_009.c
22+ * @brief Test Sequence 009 code.
23+ *
24+ * @page oslib_test_sequence_009 [9] Objects Factory
25+ *
26+ * File: @ref oslib_test_sequence_009.c
27+ *
28+ * <h2>Description</h2>
29+ * This sequence tests the ChibiOS library functionalities related to
30+ * the object factory.
31+ *
32+ * <h2>Conditions</h2>
33+ * This sequence is only executed if the following preprocessor condition
34+ * evaluates to true:
35+ * - (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)
36+ * .
37+ *
38+ * <h2>Test Cases</h2>
39+ * - @subpage oslib_test_009_001
40+ * - @subpage oslib_test_009_002
41+ * - @subpage oslib_test_009_003
42+ * - @subpage oslib_test_009_004
43+ * - @subpage oslib_test_009_005
44+ * - @subpage oslib_test_009_006
45+ * .
46+ */
47+
48+#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
49+
50+/****************************************************************************
51+ * Shared code.
52+ ****************************************************************************/
53+
54+
55+/****************************************************************************
56+ * Test cases.
57+ ****************************************************************************/
58+
59+#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
60+/**
61+ * @page oslib_test_009_001 [9.1] Objects Registry
62+ *
63+ * <h2>Description</h2>
64+ * This test case verifies the static objects registry.
65+ *
66+ * <h2>Conditions</h2>
67+ * This test is only executed if the following preprocessor condition
68+ * evaluates to true:
69+ * - CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
70+ * .
71+ *
72+ * <h2>Test Steps</h2>
73+ * - [9.1.1] Retrieving a registered object by name, must not exist.
74+ * - [9.1.2] Registering an object, it must not exists, must succeed.
75+ * - [9.1.3] Registering an object with the same name, must fail.
76+ * - [9.1.4] Retrieving the registered object by name, must exist, then
77+ * increasing the reference counter, finally releasing both
78+ * references.
79+ * - [9.1.5] Releasing the first reference to the object, must not
80+ * trigger an assertion.
81+ * - [9.1.6] Retrieving the registered object by name again, must not
82+ * exist.
83+ * .
84+ */
85+
86+static void oslib_test_009_001_teardown(void) {
87+ registered_object_t *rop;
88+
89+ rop = chFactoryFindObject("myobj");
90+ if (rop != NULL) {
91+ while (rop->element.refs > 0U) {
92+ chFactoryReleaseObject(rop);
93+ }
94+ }
95+}
96+
97+static void oslib_test_009_001_execute(void) {
98+ registered_object_t *rop;
99+
100+ /* [9.1.1] Retrieving a registered object by name, must not exist.*/
101+ test_set_step(1);
102+ {
103+ rop = chFactoryFindObject("myobj");
104+ test_assert(rop == NULL, "found");
105+ }
106+ test_end_step(1);
107+
108+ /* [9.1.2] Registering an object, it must not exists, must succeed.*/
109+ test_set_step(2);
110+ {
111+ static uint32_t myobj = 0x55aa;
112+
113+ rop = chFactoryRegisterObject("myobj", (void *)&myobj);
114+ test_assert(rop != NULL, "cannot register");
115+ }
116+ test_end_step(2);
117+
118+ /* [9.1.3] Registering an object with the same name, must fail.*/
119+ test_set_step(3);
120+ {
121+ registered_object_t *rop1;
122+ static uint32_t myobj = 0x55aa;
123+
124+ rop1 = chFactoryRegisterObject("myobj", (void *)&myobj);
125+ test_assert(rop1 == NULL, "can register");
126+ }
127+ test_end_step(3);
128+
129+ /* [9.1.4] Retrieving the registered object by name, must exist, then
130+ increasing the reference counter, finally releasing both
131+ references.*/
132+ test_set_step(4);
133+ {
134+ registered_object_t *rop1, *rop2;
135+
136+ rop1 = chFactoryFindObject("myobj");
137+ test_assert(rop1 != NULL, "not found");
138+ test_assert(*(uint32_t *)(rop1->objp) == 0x55aa, "object mismatch");
139+ test_assert(rop == rop1, "object reference mismatch");
140+ test_assert(rop1->element.refs == 2, "object reference mismatch");
141+
142+ rop2 = (registered_object_t *)chFactoryDuplicateReference(&rop1->element);
143+ test_assert(rop1 == rop2, "object reference mismatch");
144+ test_assert(*(uint32_t *)(rop2->objp) == 0x55aa, "object mismatch");
145+ test_assert(rop2->element.refs == 3, "object reference mismatch");
146+
147+ chFactoryReleaseObject(rop2);
148+ test_assert(rop1->element.refs == 2, "references mismatch");
149+
150+ chFactoryReleaseObject(rop1);
151+ test_assert(rop->element.refs == 1, "references mismatch");
152+ }
153+ test_end_step(4);
154+
155+ /* [9.1.5] Releasing the first reference to the object, must not
156+ trigger an assertion.*/
157+ test_set_step(5);
158+ {
159+ chFactoryReleaseObject(rop);
160+ }
161+ test_end_step(5);
162+
163+ /* [9.1.6] Retrieving the registered object by name again, must not
164+ exist.*/
165+ test_set_step(6);
166+ {
167+ rop = chFactoryFindObject("myobj");
168+ test_assert(rop == NULL, "found");
169+ }
170+ test_end_step(6);
171+}
172+
173+static const testcase_t oslib_test_009_001 = {
174+ "Objects Registry",
175+ NULL,
176+ oslib_test_009_001_teardown,
177+ oslib_test_009_001_execute
178+};
179+#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
180+
181+#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
182+/**
183+ * @page oslib_test_009_002 [9.2] Dynamic Buffers Factory
184+ *
185+ * <h2>Description</h2>
186+ * This test case verifies the dynamic buffers factory.
187+ *
188+ * <h2>Conditions</h2>
189+ * This test is only executed if the following preprocessor condition
190+ * evaluates to true:
191+ * - CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
192+ * .
193+ *
194+ * <h2>Test Steps</h2>
195+ * - [9.2.1] Retrieving a dynamic buffer by name, must not exist.
196+ * - [9.2.2] Creating a dynamic buffer it must not exists, must
197+ * succeed.
198+ * - [9.2.3] Creating a dynamic buffer with the same name, must fail.
199+ * - [9.2.4] Retrieving the dynamic buffer by name, must exist, then
200+ * increasing the reference counter, finally releasing both
201+ * references.
202+ * - [9.2.5] Releasing the first reference to the dynamic buffer, must
203+ * not trigger an assertion.
204+ * - [9.2.6] Retrieving the dynamic buffer by name again, must not
205+ * exist.
206+ * .
207+ */
208+
209+static void oslib_test_009_002_teardown(void) {
210+ dyn_buffer_t *dbp;
211+
212+ dbp = chFactoryFindBuffer("mybuf");
213+ if (dbp != NULL) {
214+ while (dbp->element.refs > 0U) {
215+ chFactoryReleaseBuffer(dbp);
216+ }
217+ }
218+}
219+
220+static void oslib_test_009_002_execute(void) {
221+ dyn_buffer_t *dbp;
222+
223+ /* [9.2.1] Retrieving a dynamic buffer by name, must not exist.*/
224+ test_set_step(1);
225+ {
226+ dbp = chFactoryFindBuffer("mybuf");
227+ test_assert(dbp == NULL, "found");
228+ }
229+ test_end_step(1);
230+
231+ /* [9.2.2] Creating a dynamic buffer it must not exists, must
232+ succeed.*/
233+ test_set_step(2);
234+ {
235+ dbp = chFactoryCreateBuffer("mybuf", 128U);
236+ test_assert(dbp != NULL, "cannot create");
237+ }
238+ test_end_step(2);
239+
240+ /* [9.2.3] Creating a dynamic buffer with the same name, must fail.*/
241+ test_set_step(3);
242+ {
243+ dyn_buffer_t *dbp1;
244+
245+ dbp1 = chFactoryCreateBuffer("mybuf", 128U);
246+ test_assert(dbp1 == NULL, "can create");
247+ }
248+ test_end_step(3);
249+
250+ /* [9.2.4] Retrieving the dynamic buffer by name, must exist, then
251+ increasing the reference counter, finally releasing both
252+ references.*/
253+ test_set_step(4);
254+ {
255+ dyn_buffer_t *dbp1, *dbp2;
256+
257+ dbp1 = chFactoryFindBuffer("mybuf");
258+ test_assert(dbp1 != NULL, "not found");
259+ test_assert(dbp == dbp1, "object reference mismatch");
260+ test_assert(dbp1->element.refs == 2, "object reference mismatch");
261+
262+ dbp2 = (dyn_buffer_t *)chFactoryDuplicateReference(&dbp1->element);
263+ test_assert(dbp1 == dbp2, "object reference mismatch");
264+ test_assert(dbp2->element.refs == 3, "object reference mismatch");
265+
266+ chFactoryReleaseBuffer(dbp2);
267+ test_assert(dbp1->element.refs == 2, "references mismatch");
268+
269+ chFactoryReleaseBuffer(dbp1);
270+ test_assert(dbp->element.refs == 1, "references mismatch");
271+ }
272+ test_end_step(4);
273+
274+ /* [9.2.5] Releasing the first reference to the dynamic buffer, must
275+ not trigger an assertion.*/
276+ test_set_step(5);
277+ {
278+ chFactoryReleaseBuffer(dbp);
279+ }
280+ test_end_step(5);
281+
282+ /* [9.2.6] Retrieving the dynamic buffer by name again, must not
283+ exist.*/
284+ test_set_step(6);
285+ {
286+ dbp = chFactoryFindBuffer("mybuf");
287+ test_assert(dbp == NULL, "found");
288+ }
289+ test_end_step(6);
290+}
291+
292+static const testcase_t oslib_test_009_002 = {
293+ "Dynamic Buffers Factory",
294+ NULL,
295+ oslib_test_009_002_teardown,
296+ oslib_test_009_002_execute
297+};
298+#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
299+
300+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
301+/**
302+ * @page oslib_test_009_003 [9.3] Dynamic Semaphores Factory
303+ *
304+ * <h2>Description</h2>
305+ * This test case verifies the dynamic semaphores factory.
306+ *
307+ * <h2>Conditions</h2>
308+ * This test is only executed if the following preprocessor condition
309+ * evaluates to true:
310+ * - CH_CFG_FACTORY_SEMAPHORES == TRUE
311+ * .
312+ *
313+ * <h2>Test Steps</h2>
314+ * - [9.3.1] Retrieving a dynamic semaphore by name, must not exist.
315+ * - [9.3.2] Creating a dynamic semaphore it must not exists, must
316+ * succeed.
317+ * - [9.3.3] Creating a dynamic semaphore with the same name, must
318+ * fail.
319+ * - [9.3.4] Retrieving the dynamic semaphore by name, must exist, then
320+ * increasing the reference counter, finally releasing both
321+ * references.
322+ * - [9.3.5] Releasing the first reference to the dynamic semaphore
323+ * must not trigger an assertion.
324+ * - [9.3.6] Retrieving the dynamic semaphore by name again, must not
325+ * exist.
326+ * .
327+ */
328+
329+static void oslib_test_009_003_teardown(void) {
330+ dyn_semaphore_t *dsp;
331+
332+ dsp = chFactoryFindSemaphore("mysem");
333+ if (dsp != NULL) {
334+ while (dsp->element.refs > 0U) {
335+ chFactoryReleaseSemaphore(dsp);
336+ }
337+ }
338+}
339+
340+static void oslib_test_009_003_execute(void) {
341+ dyn_semaphore_t *dsp;
342+
343+ /* [9.3.1] Retrieving a dynamic semaphore by name, must not exist.*/
344+ test_set_step(1);
345+ {
346+ dsp = chFactoryFindSemaphore("mysem");
347+ test_assert(dsp == NULL, "found");
348+ }
349+ test_end_step(1);
350+
351+ /* [9.3.2] Creating a dynamic semaphore it must not exists, must
352+ succeed.*/
353+ test_set_step(2);
354+ {
355+ dsp = chFactoryCreateSemaphore("mysem", 0);
356+ test_assert(dsp != NULL, "cannot create");
357+ }
358+ test_end_step(2);
359+
360+ /* [9.3.3] Creating a dynamic semaphore with the same name, must
361+ fail.*/
362+ test_set_step(3);
363+ {
364+ dyn_semaphore_t *dsp1;
365+
366+ dsp1 = chFactoryCreateSemaphore("mysem", 0);
367+ test_assert(dsp1 == NULL, "can create");
368+ }
369+ test_end_step(3);
370+
371+ /* [9.3.4] Retrieving the dynamic semaphore by name, must exist, then
372+ increasing the reference counter, finally releasing both
373+ references.*/
374+ test_set_step(4);
375+ {
376+ dyn_semaphore_t *dsp1, *dsp2;
377+
378+ dsp1 = chFactoryFindSemaphore("mysem");
379+ test_assert(dsp1 != NULL, "not found");
380+ test_assert(dsp == dsp1, "object reference mismatch");
381+ test_assert(dsp1->element.refs == 2, "object reference mismatch");
382+
383+ dsp2 = (dyn_semaphore_t *)chFactoryDuplicateReference(&dsp1->element);
384+ test_assert(dsp1 == dsp2, "object reference mismatch");
385+ test_assert(dsp2->element.refs == 3, "object reference mismatch");
386+
387+ chFactoryReleaseSemaphore(dsp2);
388+ test_assert(dsp1->element.refs == 2, "references mismatch");
389+
390+ chFactoryReleaseSemaphore(dsp1);
391+ test_assert(dsp->element.refs == 1, "references mismatch");
392+ }
393+ test_end_step(4);
394+
395+ /* [9.3.5] Releasing the first reference to the dynamic semaphore
396+ must not trigger an assertion.*/
397+ test_set_step(5);
398+ {
399+ chFactoryReleaseSemaphore(dsp);
400+ }
401+ test_end_step(5);
402+
403+ /* [9.3.6] Retrieving the dynamic semaphore by name again, must not
404+ exist.*/
405+ test_set_step(6);
406+ {
407+ dsp = chFactoryFindSemaphore("mysem");
408+ test_assert(dsp == NULL, "found");
409+ }
410+ test_end_step(6);
411+}
412+
413+static const testcase_t oslib_test_009_003 = {
414+ "Dynamic Semaphores Factory",
415+ NULL,
416+ oslib_test_009_003_teardown,
417+ oslib_test_009_003_execute
418+};
419+#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
420+
421+#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
422+/**
423+ * @page oslib_test_009_004 [9.4] Dynamic Mailboxes Factory
424+ *
425+ * <h2>Description</h2>
426+ * This test case verifies the dynamic mailboxes factory.
427+ *
428+ * <h2>Conditions</h2>
429+ * This test is only executed if the following preprocessor condition
430+ * evaluates to true:
431+ * - CH_CFG_FACTORY_MAILBOXES == TRUE
432+ * .
433+ *
434+ * <h2>Test Steps</h2>
435+ * - [9.4.1] Retrieving a dynamic mailbox by name, must not exist.
436+ * - [9.4.2] Creating a dynamic mailbox it must not exists, must
437+ * succeed.
438+ * - [9.4.3] Creating a dynamic mailbox with the same name, must fail.
439+ * - [9.4.4] Retrieving the dynamic mailbox by name, must exist, then
440+ * increasing the reference counter, finally releasing both
441+ * references.
442+ * - [9.4.5] Releasing the first reference to the dynamic mailbox must
443+ * not trigger an assertion.
444+ * - [9.4.6] Retrieving the dynamic mailbox by name again, must not
445+ * exist.
446+ * .
447+ */
448+
449+static void oslib_test_009_004_teardown(void) {
450+ dyn_mailbox_t *dmp;
451+
452+ dmp = chFactoryFindMailbox("mymbx");
453+ if (dmp != NULL) {
454+ while (dmp->element.refs > 0U) {
455+ chFactoryReleaseMailbox(dmp);
456+ }
457+ }
458+}
459+
460+static void oslib_test_009_004_execute(void) {
461+ dyn_mailbox_t *dmp;
462+
463+ /* [9.4.1] Retrieving a dynamic mailbox by name, must not exist.*/
464+ test_set_step(1);
465+ {
466+ dmp = chFactoryFindMailbox("mymbx");
467+ test_assert(dmp == NULL, "found");
468+ }
469+ test_end_step(1);
470+
471+ /* [9.4.2] Creating a dynamic mailbox it must not exists, must
472+ succeed.*/
473+ test_set_step(2);
474+ {
475+ dmp = chFactoryCreateMailbox("mymbx", 16U);
476+ test_assert(dmp != NULL, "cannot create");
477+ }
478+ test_end_step(2);
479+
480+ /* [9.4.3] Creating a dynamic mailbox with the same name, must
481+ fail.*/
482+ test_set_step(3);
483+ {
484+ dyn_mailbox_t *dmp1;
485+
486+ dmp1 = chFactoryCreateMailbox("mymbx", 16U);
487+ test_assert(dmp1 == NULL, "can create");
488+ }
489+ test_end_step(3);
490+
491+ /* [9.4.4] Retrieving the dynamic mailbox by name, must exist, then
492+ increasing the reference counter, finally releasing both
493+ references.*/
494+ test_set_step(4);
495+ {
496+ dyn_mailbox_t *dmp1, *dmp2;
497+
498+ dmp1 = chFactoryFindMailbox("mymbx");
499+ test_assert(dmp1 != NULL, "not found");
500+ test_assert(dmp == dmp1, "object reference mismatch");
501+ test_assert(dmp1->element.refs == 2, "object reference mismatch");
502+
503+ dmp2 = (dyn_mailbox_t *)chFactoryDuplicateReference(&dmp1->element);
504+ test_assert(dmp1 == dmp2, "object reference mismatch");
505+ test_assert(dmp2->element.refs == 3, "object reference mismatch");
506+
507+ chFactoryReleaseMailbox(dmp2);
508+ test_assert(dmp1->element.refs == 2, "references mismatch");
509+
510+ chFactoryReleaseMailbox(dmp1);
511+ test_assert(dmp->element.refs == 1, "references mismatch");
512+ }
513+ test_end_step(4);
514+
515+ /* [9.4.5] Releasing the first reference to the dynamic mailbox must
516+ not trigger an assertion.*/
517+ test_set_step(5);
518+ {
519+ chFactoryReleaseMailbox(dmp);
520+ }
521+ test_end_step(5);
522+
523+ /* [9.4.6] Retrieving the dynamic mailbox by name again, must not
524+ exist.*/
525+ test_set_step(6);
526+ {
527+ dmp = chFactoryFindMailbox("mymbx");
528+ test_assert(dmp == NULL, "found");
529+ }
530+ test_end_step(6);
531+}
532+
533+static const testcase_t oslib_test_009_004 = {
534+ "Dynamic Mailboxes Factory",
535+ NULL,
536+ oslib_test_009_004_teardown,
537+ oslib_test_009_004_execute
538+};
539+#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
540+
541+#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
542+/**
543+ * @page oslib_test_009_005 [9.5] Dynamic Objects FIFOs Factory
544+ *
545+ * <h2>Description</h2>
546+ * This test case verifies the dynamic objects FIFOs factory.
547+ *
548+ * <h2>Conditions</h2>
549+ * This test is only executed if the following preprocessor condition
550+ * evaluates to true:
551+ * - CH_CFG_FACTORY_OBJ_FIFOS == TRUE
552+ * .
553+ *
554+ * <h2>Test Steps</h2>
555+ * - [9.5.1] Retrieving a dynamic objects FIFO by name, must not exist.
556+ * - [9.5.2] Creating a dynamic objects FIFO it must not exists, must
557+ * succeed.
558+ * - [9.5.3] Creating a dynamic objects FIFO with the same name, must
559+ * fail.
560+ * - [9.5.4] Retrieving the dynamic objects FIFO by name, must exist,
561+ * then increasing the reference counter, finally releasing both
562+ * references.
563+ * - [9.5.5] Releasing the first reference to the dynamic objects FIFO
564+ * must not trigger an assertion.
565+ * - [9.5.6] Retrieving the dynamic objects FIFO by name again, must
566+ * not exist.
567+ * .
568+ */
569+
570+static void oslib_test_009_005_teardown(void) {
571+ dyn_objects_fifo_t *dofp;
572+
573+ dofp = chFactoryFindObjectsFIFO("myfifo");
574+ if (dofp != NULL) {
575+ while (dofp->element.refs > 0U) {
576+ chFactoryReleaseObjectsFIFO(dofp);
577+ }
578+ }
579+}
580+
581+static void oslib_test_009_005_execute(void) {
582+ dyn_objects_fifo_t *dofp;
583+
584+ /* [9.5.1] Retrieving a dynamic objects FIFO by name, must not
585+ exist.*/
586+ test_set_step(1);
587+ {
588+ dofp = chFactoryFindObjectsFIFO("myfifo");
589+ test_assert(dofp == NULL, "found");
590+ }
591+ test_end_step(1);
592+
593+ /* [9.5.2] Creating a dynamic objects FIFO it must not exists, must
594+ succeed.*/
595+ test_set_step(2);
596+ {
597+ dofp = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
598+ test_assert(dofp != NULL, "cannot create");
599+ }
600+ test_end_step(2);
601+
602+ /* [9.5.3] Creating a dynamic objects FIFO with the same name, must
603+ fail.*/
604+ test_set_step(3);
605+ {
606+ dyn_objects_fifo_t *dofp1;
607+
608+ dofp1 = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
609+ test_assert(dofp1 == NULL, "can create");
610+ }
611+ test_end_step(3);
612+
613+ /* [9.5.4] Retrieving the dynamic objects FIFO by name, must exist,
614+ then increasing the reference counter, finally releasing both
615+ references.*/
616+ test_set_step(4);
617+ {
618+ dyn_objects_fifo_t *dofp1, *dofp2;
619+
620+ dofp1 = chFactoryFindObjectsFIFO("myfifo");
621+ test_assert(dofp1 != NULL, "not found");
622+ test_assert(dofp == dofp1, "object reference mismatch");
623+ test_assert(dofp1->element.refs == 2, "object reference mismatch");
624+
625+ dofp2 = (dyn_objects_fifo_t *)chFactoryDuplicateReference(&dofp1->element);
626+ test_assert(dofp1 == dofp2, "object reference mismatch");
627+ test_assert(dofp2->element.refs == 3, "object reference mismatch");
628+
629+ chFactoryReleaseObjectsFIFO(dofp2);
630+ test_assert(dofp1->element.refs == 2, "references mismatch");
631+
632+ chFactoryReleaseObjectsFIFO(dofp1);
633+ test_assert(dofp->element.refs == 1, "references mismatch");
634+ }
635+ test_end_step(4);
636+
637+ /* [9.5.5] Releasing the first reference to the dynamic objects FIFO
638+ must not trigger an assertion.*/
639+ test_set_step(5);
640+ {
641+ chFactoryReleaseObjectsFIFO(dofp);
642+ }
643+ test_end_step(5);
644+
645+ /* [9.5.6] Retrieving the dynamic objects FIFO by name again, must
646+ not exist.*/
647+ test_set_step(6);
648+ {
649+ dofp = chFactoryFindObjectsFIFO("myfifo");
650+ test_assert(dofp == NULL, "found");
651+ }
652+ test_end_step(6);
653+}
654+
655+static const testcase_t oslib_test_009_005 = {
656+ "Dynamic Objects FIFOs Factory",
657+ NULL,
658+ oslib_test_009_005_teardown,
659+ oslib_test_009_005_execute
660+};
661+#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
662+
663+#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
664+/**
665+ * @page oslib_test_009_006 [9.6] Dynamic Pipes Factory
666+ *
667+ * <h2>Description</h2>
668+ * This test case verifies the dynamic pipes factory.
669+ *
670+ * <h2>Conditions</h2>
671+ * This test is only executed if the following preprocessor condition
672+ * evaluates to true:
673+ * - CH_CFG_FACTORY_PIPES == TRUE
674+ * .
675+ *
676+ * <h2>Test Steps</h2>
677+ * - [9.6.1] Retrieving a dynamic pipe by name, must not exist.
678+ * - [9.6.2] Creating a dynamic pipe it must not exists, must succeed.
679+ * - [9.6.3] Creating a dynamic pipe with the same name, must fail.
680+ * - [9.6.4] Retrieving the dynamic pipe by name, must exist, then
681+ * increasing the reference counter, finally releasing both
682+ * references.
683+ * - [9.6.5] Releasing the first reference to the dynamic pipe must not
684+ * trigger an assertion.
685+ * - [9.6.6] Retrieving the dynamic pipe by name again, must not exist.
686+ * .
687+ */
688+
689+static void oslib_test_009_006_teardown(void) {
690+ dyn_pipe_t *dpp;
691+
692+ dpp = chFactoryFindPipe("mypipe");
693+ if (dpp != NULL) {
694+ while (dpp->element.refs > 0U) {
695+ chFactoryReleasePipe(dpp);
696+ }
697+ }
698+}
699+
700+static void oslib_test_009_006_execute(void) {
701+ dyn_pipe_t *dpp;
702+
703+ /* [9.6.1] Retrieving a dynamic pipe by name, must not exist.*/
704+ test_set_step(1);
705+ {
706+ dpp = chFactoryFindPipe("mypipe");
707+ test_assert(dpp == NULL, "found");
708+ }
709+ test_end_step(1);
710+
711+ /* [9.6.2] Creating a dynamic pipe it must not exists, must
712+ succeed.*/
713+ test_set_step(2);
714+ {
715+ dpp = chFactoryCreatePipe("mypipe", 16U);
716+ test_assert(dpp != NULL, "cannot create");
717+ }
718+ test_end_step(2);
719+
720+ /* [9.6.3] Creating a dynamic pipe with the same name, must fail.*/
721+ test_set_step(3);
722+ {
723+ dyn_pipe_t *dpp1;
724+
725+ dpp1 = chFactoryCreatePipe("mypipe", 16U);
726+ test_assert(dpp1 == NULL, "can create");
727+ }
728+ test_end_step(3);
729+
730+ /* [9.6.4] Retrieving the dynamic pipe by name, must exist, then
731+ increasing the reference counter, finally releasing both
732+ references.*/
733+ test_set_step(4);
734+ {
735+ dyn_pipe_t *dpp1, *dpp2;
736+
737+ dpp1 = chFactoryFindPipe("mypipe");
738+ test_assert(dpp1 != NULL, "not found");
739+ test_assert(dpp == dpp1, "object reference mismatch");
740+ test_assert(dpp1->element.refs == 2, "object reference mismatch");
741+
742+ dpp2 = (dyn_pipe_t *)chFactoryDuplicateReference(&dpp1->element);
743+ test_assert(dpp1 == dpp2, "object reference mismatch");
744+ test_assert(dpp2->element.refs == 3, "object reference mismatch");
745+
746+ chFactoryReleasePipe(dpp2);
747+ test_assert(dpp1->element.refs == 2, "references mismatch");
748+
749+ chFactoryReleasePipe(dpp1);
750+ test_assert(dpp->element.refs == 1, "references mismatch");
751+ }
752+ test_end_step(4);
753+
754+ /* [9.6.5] Releasing the first reference to the dynamic pipe must not
755+ trigger an assertion.*/
756+ test_set_step(5);
757+ {
758+ chFactoryReleasePipe(dpp);
759+ }
760+ test_end_step(5);
761+
762+ /* [9.6.6] Retrieving the dynamic pipe by name again, must not
763+ exist.*/
764+ test_set_step(6);
765+ {
766+ dpp = chFactoryFindPipe("mypipe");
767+ test_assert(dpp == NULL, "found");
768+ }
769+ test_end_step(6);
770+}
771+
772+static const testcase_t oslib_test_009_006 = {
773+ "Dynamic Pipes Factory",
774+ NULL,
775+ oslib_test_009_006_teardown,
776+ oslib_test_009_006_execute
777+};
778+#endif /* CH_CFG_FACTORY_PIPES == TRUE */
779+
780+/****************************************************************************
781+ * Exported data.
782+ ****************************************************************************/
783+
784+/**
785+ * @brief Array of test cases.
786+ */
787+const testcase_t * const oslib_test_sequence_009_array[] = {
788+#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
789+ &oslib_test_009_001,
790+#endif
791+#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
792+ &oslib_test_009_002,
793+#endif
794+#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
795+ &oslib_test_009_003,
796+#endif
797+#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
798+ &oslib_test_009_004,
799+#endif
800+#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
801+ &oslib_test_009_005,
802+#endif
803+#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
804+ &oslib_test_009_006,
805+#endif
806+ NULL
807+};
808+
809+/**
810+ * @brief Objects Factory.
811+ */
812+const testsequence_t oslib_test_sequence_009 = {
813+ "Objects Factory",
814+ oslib_test_sequence_009_array
815+};
816+
817+#endif /* (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) */
--- trunk/test/oslib/source/test/oslib_test_sequence_009.h (nonexistent)
+++ trunk/test/oslib/source/test/oslib_test_sequence_009.h (revision 13204)
@@ -0,0 +1,27 @@
1+/*
2+ ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ http://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+*/
16+
17+/**
18+ * @file oslib_test_sequence_009.h
19+ * @brief Test Sequence 009 header.
20+ */
21+
22+#ifndef OSLIB_TEST_SEQUENCE_009_H
23+#define OSLIB_TEST_SEQUENCE_009_H
24+
25+extern const testsequence_t oslib_test_sequence_009;
26+
27+#endif /* OSLIB_TEST_SEQUENCE_009_H */
--- trunk/test/oslib/configuration.xml (revision 13203)
+++ trunk/test/oslib/configuration.xml (revision 13204)
@@ -1023,6 +1023,158 @@
10231023 <value>Internal Tests</value>
10241024 </type>
10251025 <brief>
1026+ <value>Jobs Queues</value>
1027+ </brief>
1028+ <description>
1029+ <value>This sequence tests the ChibiOS library functionalities related to Jobs Queues.</value>
1030+ </description>
1031+ <condition>
1032+ <value>CH_CFG_USE_JOBS</value>
1033+ </condition>
1034+ <shared_code>
1035+ <value><![CDATA[
1036+#define JOBS_QUEUE_SIZE 4
1037+
1038+static jobs_queue_t jq;
1039+static job_descriptor_t jobs[JOBS_QUEUE_SIZE];
1040+static msg_t msg_queue[JOBS_QUEUE_SIZE];
1041+
1042+static void job_slow(void *arg) {
1043+
1044+ test_emit_token((int)arg);
1045+ chThdSleepMilliseconds(10);
1046+}
1047+
1048+static THD_WORKING_AREA(wa1Thread1, 256);
1049+static THD_WORKING_AREA(wa2Thread1, 256);
1050+static THD_FUNCTION(Thread1, arg) {
1051+ msg_t msg;
1052+
1053+ (void)arg;
1054+
1055+ do {
1056+ msg = chJobDispatch(&jq);
1057+ } while (msg == MSG_OK);
1058+}
1059+]]></value>
1060+ </shared_code>
1061+ <cases>
1062+ <case>
1063+ <brief>
1064+ <value>Dispatcher test.</value>
1065+ </brief>
1066+ <description>
1067+ <value>The dispatcher API is tested for functionality.</value>
1068+ </description>
1069+ <condition>
1070+ <value>
1071+ </value>
1072+ </condition>
1073+ <various_code>
1074+ <setup_code>
1075+ <value/>
1076+ </setup_code>
1077+ <teardown_code>
1078+ <value/>
1079+ </teardown_code>
1080+ <local_variables>
1081+ <value><![CDATA[
1082+thread_t *tp1, *tp2;
1083+]]></value>
1084+ </local_variables>
1085+ </various_code>
1086+ <steps>
1087+ <step>
1088+ <description>
1089+ <value>Initializing the Jobs Queue object.</value>
1090+ </description>
1091+ <tags>
1092+ <value></value>
1093+ </tags>
1094+ <code>
1095+ <value><![CDATA[
1096+chJobObjectInit(&jq, JOBS_QUEUE_SIZE, jobs, msg_queue);
1097+]]></value>
1098+ </code>
1099+ </step>
1100+ <step>
1101+ <description>
1102+ <value>Starting the dispatcher threads.</value>
1103+ </description>
1104+ <tags>
1105+ <value></value>
1106+ </tags>
1107+ <code>
1108+ <value><![CDATA[
1109+thread_descriptor_t td1 = {
1110+ .name = "dispatcher1",
1111+ .wbase = wa1Thread1,
1112+ .wend = THD_WORKING_AREA_END(wa1Thread1),
1113+ .prio = chThdGetPriorityX() - 1,
1114+ .funcp = Thread1,
1115+ .arg = NULL
1116+};
1117+tp1 = chThdCreate(&td1);
1118+
1119+thread_descriptor_t td2 = {
1120+ .name = "dispatcher2",
1121+ .wbase = wa2Thread1,
1122+ .wend = THD_WORKING_AREA_END(wa2Thread1),
1123+ .prio = chThdGetPriorityX() - 1,
1124+ .funcp = Thread1,
1125+ .arg = NULL
1126+};
1127+tp2 = chThdCreate(&td2);
1128+]]></value>
1129+ </code>
1130+ </step>
1131+ <step>
1132+ <description>
1133+ <value>Sending jobs with various timings.</value>
1134+ </description>
1135+ <tags>
1136+ <value></value>
1137+ </tags>
1138+ <code>
1139+ <value><![CDATA[
1140+unsigned i;
1141+job_descriptor_t *jdp;
1142+
1143+for (i = 0; i < 8; i++) {
1144+ jdp = chJobGet(&jq);
1145+ jdp->jobfunc = job_slow;
1146+ jdp->jobarg = (void *)('a' + i);
1147+ chJobPost(&jq, jdp);
1148+}
1149+]]></value>
1150+ </code>
1151+ </step>
1152+ <step>
1153+ <description>
1154+ <value>Sending null jobs to make thread exit.</value>
1155+ </description>
1156+ <tags>
1157+ <value></value>
1158+ </tags>
1159+ <code>
1160+ <value><![CDATA[
1161+chJobPost(&jq, JOB_NULL);
1162+chJobPost(&jq, JOB_NULL);
1163+(void) chThdWait(tp1);
1164+(void) chThdWait(tp2);
1165+test_assert_sequence("abcdefgh", "unexpected tokens");
1166+]]></value>
1167+ </code>
1168+ </step>
1169+ </steps>
1170+ </case>
1171+ </cases>
1172+ </sequence>
1173+ <sequence>
1174+ <type index="0">
1175+ <value>Internal Tests</value>
1176+ </type>
1177+ <brief>
10261178 <value>Thread Delegates</value>
10271179 </brief>
10281180 <description>
Show on old repository browser