ChibiOS/RT 7.0.6
chfactory.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 This file is part of ChibiOS.
5
6 ChibiOS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 3 of the License.
9
10 ChibiOS is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file oslib/src/chfactory.c
21 * @brief ChibiOS objects factory and registry code.
22 *
23 * @addtogroup oslib_objects_factory
24 * @details The object factory is a subsystem that allows to:
25 * - Register static objects by name.
26 * - Dynamically create objects and assign them a name.
27 * - Retrieve existing objects by name.
28 * - Free objects by reference.
29 * .
30 * Allocated OS objects are handled using a reference counter, only
31 * when all references have been released then the object memory is
32 * freed in a pool.<br>
33 * @pre This subsystem requires the @p CH_CFG_USE_MEMCORE and
34 * @p CH_CFG_USE_MEMPOOLS options to be set to @p TRUE. The
35 * option @p CH_CFG_USE_HEAP is also required if the support
36 * for variable length objects is enabled.
37 * @note Compatible with RT and NIL.
38 * @{
39 */
40
41#include <string.h>
42
43#include "ch.h"
44
45#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
46
47/*===========================================================================*/
48/* Module local definitions. */
49/*===========================================================================*/
50
51/*
52 * Defaults on the best synchronization mechanism available.
53 */
54#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
55#define F_LOCK() chMtxLock(&ch_factory.mtx)
56#define F_UNLOCK() chMtxUnlock(&ch_factory.mtx)
57#else
58#define F_LOCK() (void) chSemWait(&ch_factory.sem)
59#define F_UNLOCK() chSemSignal(&ch_factory.sem)
60#endif
61
62/*===========================================================================*/
63/* Module exported variables. */
64/*===========================================================================*/
65
66/**
67 * @brief Factory object static instance.
68 * @note It is a global object because it could be accessed through
69 * a specific debugger plugin.
70 */
72
73/*===========================================================================*/
74/* Module local types. */
75/*===========================================================================*/
76
77/*===========================================================================*/
78/* Module local variables. */
79/*===========================================================================*/
80
81/*===========================================================================*/
82/* Module local functions. */
83/*===========================================================================*/
84
85#if CH_FACTORY_REQUIRES_HEAP || defined(__DOXYGEN__)
86static bool add_size(size_t a, size_t b, size_t *result) {
87
88 if (a > ((size_t)-1) - b) {
89 return true;
90 }
91
92 *result = a + b;
93
94 return false;
95}
96#endif /* CH_FACTORY_REQUIRES_HEAP */
97
98#if ((CH_CFG_FACTORY_MAILBOXES == TRUE) || \
99 (CH_CFG_FACTORY_OBJ_FIFOS == TRUE)) || defined(__DOXYGEN__)
100static bool mul_size(size_t a, size_t b, size_t *result) {
101
102 if ((a != (size_t)0) && (b > ((size_t)-1) / a)) {
103 return true;
104 }
105
106 *result = a * b;
107
108 return false;
109}
110#endif /* CH_CFG_FACTORY_MAILBOXES || CH_CFG_FACTORY_OBJ_FIFOS */
111
112#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
113static bool align_size(size_t size, unsigned align, size_t *result) {
114 size_t aligned;
115
116 aligned = MEM_ALIGN_NEXT(size, align);
117 if (aligned < size) {
118 return true;
119 }
120
121 *result = aligned;
122
123 return false;
124}
125#endif /* CH_CFG_FACTORY_OBJ_FIFOS */
126
127static void copy_name(const char *sp, char *dp) {
128 unsigned i;
129 char c;
130
132 do {
133 c = *sp++;
134 *dp++ = c;
135 i--;
136 } while ((c != (char)0) && (i > 0U));
137}
138
139static inline void dyn_list_init(dyn_list_t *dlp) {
140
141 dlp->next = (dyn_element_t *)dlp;
142}
143
144static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) {
145 dyn_element_t *p = dlp->next;
146
147 while (p != (dyn_element_t *)dlp) {
148 if (strncmp(p->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH) == 0) {
149 return p;
150 }
151 p = p->next;
152 }
153
154 return NULL;
155}
156
158 dyn_list_t *dlp) {
159 dyn_element_t *prev = (dyn_element_t *)dlp;
160
161 /* Scanning the list.*/
162 while (prev->next != (dyn_element_t *)dlp) {
163 if (prev->next == element) {
164 return prev;
165 }
166
167 /* Next element in the list.*/
168 prev = prev->next;
169 }
170
171 return NULL;
172}
173
175 dyn_element_t *element = prev->next;
176
177 prev->next = element->next;
178
179 return element;
180}
181
182#if CH_FACTORY_REQUIRES_HEAP || defined(__DOXYGEN__)
183static dyn_element_t *dyn_create_object_heap(const char *name,
184 dyn_list_t *dlp,
185 size_t size,
186 unsigned align) {
187 dyn_element_t *dep;
188
189 chDbgCheck(name != NULL);
190
191 /* Checking if an object with this name has already been created.*/
192 dep = dyn_list_find(name, dlp);
193 if (dep != NULL) {
194 return NULL;
195 }
196
197 /* Allocating space for the new buffer object.*/
198 dep = (dyn_element_t *)chHeapAllocAligned(NULL, size, align);
199 if (dep == NULL) {
200 return NULL;
201 }
202
203 /* Initializing object list element.*/
204 copy_name(name, dep->name);
205 dep->refs = (ucnt_t)1;
206 dep->next = dlp->next;
207
208 /* Updating factory list.*/
209 dlp->next = dep;
210
211 return dep;
212}
213
215 dyn_list_t *dlp) {
216 dyn_element_t *prev;
217 ucnt_t refs;
218
219 chDbgCheck(dep != NULL);
220
221 /* Checking 1st if the object is in the list.*/
222 prev = dyn_list_find_prev(dep, dlp);
223 if (prev != NULL) {
224
225 chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
226
227 refs = --dep->refs;
228 if (refs == (ucnt_t)0) {
229 chHeapFree((void *)dyn_list_unlink(prev));
230 }
231 }
232 else {
233 chDbgAssert(false, "unknown object");
234 }
235}
236#endif /* CH_FACTORY_REQUIRES_HEAP */
237
238#if CH_FACTORY_REQUIRES_POOLS || defined(__DOXYGEN__)
239static dyn_element_t *dyn_create_object_pool(const char *name,
240 dyn_list_t *dlp,
241 memory_pool_t *mp) {
242 dyn_element_t *dep;
243
244 chDbgCheck(name != NULL);
245
246 /* Checking if an object object with this name has already been created.*/
247 dep = dyn_list_find(name, dlp);
248 if (dep != NULL) {
249 return NULL;
250 }
251
252 /* Allocating space for the new object.*/
253 dep = (dyn_element_t *)chPoolAlloc(mp);
254 if (dep == NULL) {
255 return NULL;
256 }
257
258 /* Initializing object list element.*/
259 copy_name(name, dep->name);
260 dep->refs = (ucnt_t)1;
261 dep->next = dlp->next;
262
263 /* Updating factory list.*/
264 dlp->next = (dyn_element_t *)dep;
265
266 return dep;
267}
268
270 dyn_list_t *dlp,
271 memory_pool_t *mp) {
272 dyn_element_t *prev;
273 ucnt_t refs;
274
275 chDbgCheck(dep != NULL);
276
277 /* Checking 1st if the object is in the list.*/
278 prev = dyn_list_find_prev(dep, dlp);
279 if (prev != NULL) {
280
281 chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
282
283 refs = --dep->refs;
284 if (refs == (ucnt_t)0) {
285 chPoolFree(mp, (void *)dyn_list_unlink(prev));
286 }
287 }
288 else {
289 chDbgAssert(false, "unknown object");
290 }
291}
292#endif /* CH_FACTORY_REQUIRES_POOLS */
293
294static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) {
295 dyn_element_t *dep;
296
297 chDbgCheck(name != NULL);
298
299 /* Checking if an object with this name has already been created.*/
300 dep = dyn_list_find(name, dlp);
301 if (dep != NULL) {
302 /* Increasing references counter.*/
303 dep->refs++;
304 }
305
306 return dep;
307}
308
309/*===========================================================================*/
310/* Module exported functions. */
311/*===========================================================================*/
312
313/**
314 * @brief Initializes the objects factory.
315 *
316 * @init
317 */
318void __factory_init(void) {
319
320#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
322#else
324#endif
325
326#if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
327 dyn_list_init(&ch_factory.obj_list);
329 sizeof (registered_object_t),
331#endif
332#if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
333 dyn_list_init(&ch_factory.buf_list);
334#endif
335#if CH_CFG_FACTORY_SEMAPHORES == TRUE
336 dyn_list_init(&ch_factory.sem_list);
338 sizeof (dyn_semaphore_t),
340#endif
341#if CH_CFG_FACTORY_MAILBOXES == TRUE
342 dyn_list_init(&ch_factory.mbx_list);
343#endif
344#if CH_CFG_FACTORY_OBJ_FIFOS == TRUE
345 dyn_list_init(&ch_factory.fifo_list);
346#endif
347#if CH_CFG_FACTORY_PIPES == TRUE
348 dyn_list_init(&ch_factory.pipe_list);
349#endif
350}
351
352/**
353 * @brief Duplicates an object reference.
354 * @note This function can be used on any kind of dynamic object.
355 *
356 * @param[in] dep pointer to the element field of the object
357 * @return The duplicated object reference.
358 *
359 * @api
360 */
362
363 chDbgCheck(dep != NULL);
364
365 F_LOCK();
366
367 chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
368 dep->refs++;
369
370 F_UNLOCK();
371
372 return dep;
373}
374
375#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
376/**
377 * @brief Registers a generic object.
378 * @post A reference to the registered object is returned and the
379 * reference counter is initialized to one.
380 *
381 * @param[in] name name to be assigned to the registered object
382 * @param[in] objp pointer to the object to be registered
383 *
384 * @return The reference to the registered object.
385 * @retval NULL if the object to be registered cannot be allocated or
386 * a registered object with the same name exists.
387 *
388 * @api
389 */
391 void *objp) {
393
394 F_LOCK();
395
397 &ch_factory.obj_list,
398 &ch_factory.obj_pool);
399 if (rop != NULL) {
400 /* Initializing registered object data.*/
401 rop->objp = objp;
402 }
403
404 F_UNLOCK();
405
406 return rop;
407}
408
409/**
410 * @brief Retrieves a registered object.
411 * @post A reference to the registered object is returned with the
412 * reference counter increased by one.
413 *
414 * @param[in] name name of the registered object
415 *
416 * @return The reference to the found registered object.
417 * @retval NULL if a registered object with the specified name
418 * does not exist.
419 *
420 * @api
421 */
424
425 F_LOCK();
426
427 rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list);
428
429 F_UNLOCK();
430
431 return rop;
432}
433
434/**
435 * @brief Retrieves a registered object by pointer.
436 * @post A reference to the registered object is returned with the
437 * reference counter increased by one.
438 *
439 * @param[in] objp pointer to the object to be retrieved
440 *
441 * @return The reference to the found registered object.
442 * @retval NULL if a registered object with the specified pointer
443 * does not exist.
444 *
445 * @api
446 */
449
450 F_LOCK();
451
452 rop = (registered_object_t *)ch_factory.obj_list.next;
453 while ((void *)rop != (void *)&ch_factory.obj_list) {
454 if (rop->objp == objp) {
455 rop->element.refs++;
456
457 F_UNLOCK();
458
459 return rop;
460 }
461 rop = (registered_object_t *)rop->element.next;
462 }
463
464 F_UNLOCK();
465
466 return NULL;
467}
468
469/**
470 * @brief Releases a registered object.
471 * @details The reference counter of the registered object is decreased
472 * by one, if reaches zero then the registered object memory
473 * is freed.
474 * @note The object itself is not freed, it could be static, only the
475 * allocated list element is freed.
476 *
477 * @param[in] rop registered object reference
478 *
479 * @api
480 */
482
483 F_LOCK();
484
486 &ch_factory.obj_list,
487 &ch_factory.obj_pool);
488
489 F_UNLOCK();
490}
491#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
492
493#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
494/**
495 * @brief Creates a generic dynamic buffer object.
496 * @post A reference to the dynamic buffer object is returned and the
497 * reference counter is initialized to one.
498 * @post The dynamic buffer object is filled with zeros.
499 *
500 * @param[in] name name to be assigned to the new dynamic buffer object
501 * @param[in] size payload size of the dynamic buffer object to be created
502 *
503 * @return The reference to the created dynamic buffer object.
504 * @retval NULL if the dynamic buffer object cannot be allocated or
505 * a dynamic buffer object with the same name exists.
506 *
507 * @api
508 */
509dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
510 size_t alloc_size;
511 dyn_buffer_t *dbp;
512
513 if (add_size(sizeof (dyn_buffer_t), size, &alloc_size)) {
514 return NULL;
515 }
516
517 F_LOCK();
518
520 &ch_factory.buf_list,
521 alloc_size,
523 if (dbp != NULL) {
524 /* Initializing buffer object data.*/
525 memset((void *)(dbp + 1), 0, size);
526 }
527
528 F_UNLOCK();
529
530 return dbp;
531}
532
533/**
534 * @brief Retrieves a dynamic buffer object.
535 * @post A reference to the dynamic buffer object is returned with the
536 * reference counter increased by one.
537 *
538 * @param[in] name name of the dynamic buffer object
539 *
540 * @return The reference to the found dynamic buffer object.
541 * @retval NULL if a dynamic buffer object with the specified name
542 * does not exist.
543 *
544 * @api
545 */
547 dyn_buffer_t *dbp;
548
549 F_LOCK();
550
551 dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list);
552
553 F_UNLOCK();
554
555 return dbp;
556}
557
558/**
559 * @brief Releases a dynamic buffer object.
560 * @details The reference counter of the dynamic buffer object is decreased
561 * by one, if reaches zero then the dynamic buffer object memory
562 * is freed.
563 *
564 * @param[in] dbp dynamic buffer object reference
565 *
566 * @api
567 */
569
570 F_LOCK();
571
573
574 F_UNLOCK();
575}
576#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
577
578#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
579/**
580 * @brief Creates a dynamic semaphore object.
581 * @post A reference to the dynamic semaphore object is returned and the
582 * reference counter is initialized to one.
583 * @post The dynamic semaphore object is initialized and ready to use.
584 *
585 * @param[in] name name to be assigned to the new dynamic semaphore object
586 * @param[in] n dynamic semaphore object counter initialization value
587 *
588 * @return The reference to the created dynamic semaphore object.
589 * @retval NULL if the dynamic semaphore object cannot be allocated or
590 * a dynamic semaphore with the same name exists.
591 *
592 * @api
593 */
595 dyn_semaphore_t *dsp;
596
597 F_LOCK();
598
600 &ch_factory.sem_list,
601 &ch_factory.sem_pool);
602 if (dsp != NULL) {
603 /* Initializing semaphore object dataa.*/
604 chSemObjectInit(&dsp->sem, n);
605 }
606
607 F_UNLOCK();
608
609 return dsp;
610}
611
612/**
613 * @brief Retrieves a dynamic semaphore object.
614 * @post A reference to the dynamic semaphore object is returned with the
615 * reference counter increased by one.
616 *
617 * @param[in] name name of the dynamic semaphore object
618 *
619 * @return The reference to the found dynamic semaphore object.
620 * @retval NULL if a dynamic semaphore object with the specified name
621 * does not exist.
622 *
623 * @api
624 */
626 dyn_semaphore_t *dsp;
627
628 F_LOCK();
629
630 dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list);
631
632 F_UNLOCK();
633
634 return dsp;
635}
636
637/**
638 * @brief Releases a dynamic semaphore object.
639 * @details The reference counter of the dynamic semaphore object is decreased
640 * by one, if reaches zero then the dynamic semaphore object memory
641 * is freed.
642 *
643 * @param[in] dsp dynamic semaphore object reference
644 *
645 * @api
646 */
648
649 F_LOCK();
650
652 &ch_factory.sem_list,
653 &ch_factory.sem_pool);
654
655 F_UNLOCK();
656}
657#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
658
659#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXIGEN__)
660/**
661 * @brief Creates a dynamic mailbox object.
662 * @post A reference to the dynamic mailbox object is returned and the
663 * reference counter is initialized to one.
664 * @post The dynamic mailbox object is initialized and ready to use.
665 *
666 * @param[in] name name to be assigned to the new dynamic mailbox object
667 * @param[in] n mailbox buffer size as number of messages
668 *
669 * @return The reference to the created dynamic mailbox object.
670 * @retval NULL if the dynamic mailbox object cannot be allocated or
671 * a dynamic mailbox object with the same name exists.
672 *
673 * @api
674 */
675dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n) {
676 size_t buffer_size, alloc_size;
677 dyn_mailbox_t *dmp;
678
679 if (mul_size(n, sizeof (msg_t), &buffer_size) ||
680 add_size(sizeof (dyn_mailbox_t), buffer_size, &alloc_size)) {
681 return NULL;
682 }
683
684 F_LOCK();
685
687 &ch_factory.mbx_list,
688 alloc_size,
690 if (dmp != NULL) {
691 /* Initializing mailbox object data.*/
692 chMBObjectInit(&dmp->mbx, (msg_t *)(dmp + 1), n);
693 }
694
695 F_UNLOCK();
696
697 return dmp;
698}
699
700/**
701 * @brief Retrieves a dynamic mailbox object.
702 * @post A reference to the dynamic mailbox object is returned with the
703 * reference counter increased by one.
704 *
705 * @param[in] name name of the dynamic mailbox object
706 *
707 * @return The reference to the found dynamic mailbox object.
708 * @retval NULL if a dynamic mailbox object with the specified name
709 * does not exist.
710 *
711 * @api
712 */
714 dyn_mailbox_t *dmp;
715
716 F_LOCK();
717
718 dmp = (dyn_mailbox_t *)dyn_find_object(name, &ch_factory.mbx_list);
719
720 F_UNLOCK();
721
722 return dmp;
723}
724
725/**
726 * @brief Releases a dynamic mailbox object.
727 * @details The reference counter of the dynamic mailbox object is decreased
728 * by one, if reaches zero then the dynamic mailbox object memory
729 * is freed.
730 *
731 * @param[in] dmp dynamic mailbox object reference
732 *
733 * @api
734 */
736
737 F_LOCK();
738
740
741 F_UNLOCK();
742}
743#endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */
744
745#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXIGEN__)
746/**
747 * @brief Creates a dynamic "objects FIFO" object.
748 * @post A reference to the dynamic "objects FIFO" object is returned and
749 * the reference counter is initialized to one.
750 * @post The dynamic "objects FIFO" object is initialized and ready to use.
751 *
752 * @param[in] name name to be assigned to the new dynamic "objects FIFO"
753 * object
754 * @param[in] objsize size of objects
755 * @param[in] objn number of objects available
756 * @param[in] objalign required objects alignment
757 * @return The reference to the created dynamic "objects FIFO"
758 * object.
759 * @retval NULL if the dynamic "objects FIFO" object cannot be
760 * allocated or a dynamic "objects FIFO" object with
761 * the same name exists.
762 *
763 * @api
764 */
766 size_t objsize,
767 size_t objn,
768 unsigned objalign) {
769 size_t msgbuf_size, size1, size2, alloc_size;
770 dyn_objects_fifo_t *dofp;
771
772 chDbgCheck((objalign >= PORT_NATURAL_ALIGN) &&
773 MEM_IS_VALID_ALIGNMENT(objalign));
774
775 if (align_size(objsize, objalign, &objsize) ||
776 mul_size(objn, sizeof (msg_t), &msgbuf_size) ||
777 add_size(sizeof (dyn_objects_fifo_t), msgbuf_size, &size1) ||
778 align_size(size1, objalign, &size1) ||
779 mul_size(objn, objsize, &size2) ||
780 add_size(size1, size2, &alloc_size)) {
781 return NULL;
782 }
783
784 F_LOCK();
785
786 /* Allocating the FIFO object with messages buffer and objects buffer.*/
788 &ch_factory.fifo_list,
789 alloc_size,
790 objalign);
791 if (dofp != NULL) {
792 msg_t *msgbuf = (msg_t *)(dofp + 1);
793 uint8_t *objbuf = (uint8_t *)dofp + size1;
794
795 /* Initializing mailbox object data.*/
796 chFifoObjectInitAligned(&dofp->fifo, objsize, objn, objalign,
797 (void *)objbuf, msgbuf);
798 }
799
800 F_UNLOCK();
801
802 return dofp;
803}
804
805/**
806 * @brief Retrieves a dynamic "objects FIFO" object.
807 * @post A reference to the dynamic "objects FIFO" object is returned with
808 * the reference counter increased by one.
809 *
810 * @param[in] name name of the dynamic "objects FIFO" object
811 *
812 * @return The reference to the found dynamic "objects FIFO"
813 * object.
814 * @retval NULL if a dynamic "objects FIFO" object with the specified
815 * name does not exist.
816 *
817 * @api
818 */
820 dyn_objects_fifo_t *dofp;
821
822 F_LOCK();
823
824 dofp = (dyn_objects_fifo_t *)dyn_find_object(name, &ch_factory.fifo_list);
825
826 F_UNLOCK();
827
828 return dofp;
829}
830
831/**
832 * @brief Releases a dynamic "objects FIFO" object.
833 * @details The reference counter of the dynamic "objects FIFO" object is
834 * decreased by one, if reaches zero then the dynamic "objects FIFO"
835 * object memory is freed.
836 *
837 * @param[in] dofp dynamic "objects FIFO" object reference
838 *
839 * @api
840 */
842
843 F_LOCK();
844
845 dyn_release_object_heap(&dofp->element, &ch_factory.fifo_list);
846
847 F_UNLOCK();
848}
849#endif /* CH_CFG_FACTORY_OBJ_FIFOS = TRUE */
850
851#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXIGEN__)
852/**
853 * @brief Creates a dynamic pipe object.
854 * @post A reference to the dynamic pipe object is returned and
855 * the reference counter is initialized to one.
856 * @post The dynamic pipe object is initialized and ready to use.
857 *
858 * @param[in] name name to be assigned to the new dynamic pipe
859 * object
860 * @param[in] size pipe buffer size
861 * @return The reference to the created dynamic pipe
862 * object.
863 * @retval NULL if the dynamic pipe object cannot be
864 * allocated or a dynamic pipe object with
865 * the same name exists.
866 *
867 * @api
868 */
869dyn_pipe_t *chFactoryCreatePipe(const char *name, size_t size) {
870 size_t alloc_size;
871 dyn_pipe_t *dpp;
872
873 if (add_size(sizeof (dyn_pipe_t), size, &alloc_size)) {
874 return NULL;
875 }
876
877 F_LOCK();
878
880 &ch_factory.pipe_list,
881 alloc_size,
883 if (dpp != NULL) {
884 /* Initializing mailbox object data.*/
885 chPipeObjectInit(&dpp->pipe, (uint8_t *)(dpp + 1), size);
886 }
887
888 F_UNLOCK();
889
890 return dpp;
891}
892
893/**
894 * @brief Retrieves a dynamic pipe object.
895 * @post A reference to the dynamic pipe object is returned with
896 * the reference counter increased by one.
897 *
898 * @param[in] name name of the pipe object
899 *
900 * @return The reference to the found dynamic pipe
901 * object.
902 * @retval NULL if a dynamic pipe object with the specified
903 * name does not exist.
904 *
905 * @api
906 */
907dyn_pipe_t *chFactoryFindPipe(const char *name) {
908 dyn_pipe_t *dpp;
909
910 F_LOCK();
911
912 dpp = (dyn_pipe_t *)dyn_find_object(name, &ch_factory.pipe_list);
913
914 F_UNLOCK();
915
916 return dpp;
917}
918
919/**
920 * @brief Releases a dynamic pipe object.
921 * @details The reference counter of the dynamic pipe object is
922 * decreased by one, if reaches zero then the dynamic pipe
923 * object memory is freed.
924 *
925 * @param[in] dpp dynamic pipe object reference
926 *
927 * @api
928 */
930
931 F_LOCK();
932
933 dyn_release_object_heap(&dpp->element, &ch_factory.pipe_list);
934
935 F_UNLOCK();
936}
937#endif /* CH_CFG_FACTORY_PIPES = TRUE */
938
939#endif /* CH_CFG_USE_FACTORY == TRUE */
940
941/** @} */
ChibiOS/RT main include file.
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:143
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:117
#define CH_CFG_FACTORY_MAX_NAMES_LENGTH
Maximum length for object names.
Definition chconf.h:495
#define MEM_IS_VALID_ALIGNMENT(a)
Returns whatever a constant is a valid alignment.
Definition chalign.h:98
#define MEM_ALIGN_NEXT(p, a)
Aligns to the next aligned memory address.
Definition chalign.h:79
void chMtxObjectInit(mutex_t *mp)
Initializes s mutex_t structure.
Definition chmtx.c:102
int32_t cnt_t
Definition chearly.h:91
int32_t msg_t
Definition chearly.h:87
uint32_t ucnt_t
Definition chearly.h:92
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n)
Initializes a mailbox_t object.
Definition chmboxes.c:86
static void * chCoreAllocAlignedI(size_t size, unsigned align)
Allocates a memory block.
Definition chmemcore.h:149
void chHeapFree(void *p)
Frees a previously allocated memory block.
Definition chmemheaps.c:299
void * chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align)
Allocates a block of memory from the heap by using the first-fit algorithm.
Definition chmemheaps.c:171
#define CH_HEAP_ALIGNMENT
Minimum alignment used for heap.
Definition chmemheaps.h:41
void * chPoolAlloc(memory_pool_t *mp)
Allocates an object from a memory pool.
Definition chmempools.c:160
static void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider)
Initializes an empty memory pool.
Definition chmempools.h:188
void chPoolFree(memory_pool_t *mp, void *objp)
Releases an object into a memory pool.
Definition chmempools.c:206
struct ch_dyn_objects_fifo dyn_objects_fifo_t
Type of a dynamic buffer object.
struct ch_dyn_element dyn_element_t
Type of a dynamic object list element.
#define F_UNLOCK()
Definition chfactory.c:56
dyn_mailbox_t * chFactoryFindMailbox(const char *name)
Retrieves a dynamic mailbox object.
Definition chfactory.c:713
static dyn_element_t * dyn_list_unlink(dyn_element_t *prev)
Definition chfactory.c:174
void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp)
Releases a dynamic "objects FIFO" object.
Definition chfactory.c:841
static void copy_name(const char *sp, char *dp)
Definition chfactory.c:127
struct ch_dyn_object dyn_buffer_t
Type of a dynamic buffer object.
static dyn_element_t * dyn_create_object_pool(const char *name, dyn_list_t *dlp, memory_pool_t *mp)
Definition chfactory.c:239
static bool align_size(size_t size, unsigned align, size_t *result)
Definition chfactory.c:113
void chFactoryReleaseObject(registered_object_t *rop)
Releases a registered object.
Definition chfactory.c:481
struct ch_dyn_list dyn_list_t
Type of a dynamic object list.
objects_factory_t ch_factory
Factory object static instance.
Definition chfactory.c:71
struct ch_dyn_semaphore dyn_semaphore_t
Type of a dynamic semaphore.
dyn_semaphore_t * chFactoryCreateSemaphore(const char *name, cnt_t n)
Creates a dynamic semaphore object.
Definition chfactory.c:594
dyn_objects_fifo_t * chFactoryFindObjectsFIFO(const char *name)
Retrieves a dynamic "objects FIFO" object.
Definition chfactory.c:819
static void dyn_release_object_heap(dyn_element_t *dep, dyn_list_t *dlp)
Definition chfactory.c:214
registered_object_t * chFactoryFindObjectByPointer(void *objp)
Retrieves a registered object by pointer.
Definition chfactory.c:447
static bool mul_size(size_t a, size_t b, size_t *result)
Definition chfactory.c:100
void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp)
Releases a dynamic semaphore object.
Definition chfactory.c:647
dyn_buffer_t * chFactoryFindBuffer(const char *name)
Retrieves a dynamic buffer object.
Definition chfactory.c:546
dyn_semaphore_t * chFactoryFindSemaphore(const char *name)
Retrieves a dynamic semaphore object.
Definition chfactory.c:625
static dyn_element_t * dyn_create_object_heap(const char *name, dyn_list_t *dlp, size_t size, unsigned align)
Definition chfactory.c:183
static bool add_size(size_t a, size_t b, size_t *result)
Definition chfactory.c:86
dyn_pipe_t * chFactoryCreatePipe(const char *name, size_t size)
Creates a dynamic pipe object.
Definition chfactory.c:869
static void dyn_list_init(dyn_list_t *dlp)
Definition chfactory.c:139
void chFactoryReleasePipe(dyn_pipe_t *dpp)
Releases a dynamic pipe object.
Definition chfactory.c:929
struct ch_dyn_pipe dyn_pipe_t
Type of a dynamic pipe object.
struct ch_dyn_mailbox dyn_mailbox_t
Type of a dynamic buffer object.
dyn_mailbox_t * chFactoryCreateMailbox(const char *name, size_t n)
Creates a dynamic mailbox object.
Definition chfactory.c:675
#define F_LOCK()
Definition chfactory.c:55
dyn_objects_fifo_t * chFactoryCreateObjectsFIFO(const char *name, size_t objsize, size_t objn, unsigned objalign)
Creates a dynamic "objects FIFO" object.
Definition chfactory.c:765
registered_object_t * chFactoryFindObject(const char *name)
Retrieves a registered object.
Definition chfactory.c:422
void chFactoryReleaseBuffer(dyn_buffer_t *dbp)
Releases a dynamic buffer object.
Definition chfactory.c:568
void __factory_init(void)
Initializes the objects factory.
Definition chfactory.c:318
void chFactoryReleaseMailbox(dyn_mailbox_t *dmp)
Releases a dynamic mailbox object.
Definition chfactory.c:735
static dyn_element_t * dyn_list_find_prev(dyn_element_t *element, dyn_list_t *dlp)
Definition chfactory.c:157
struct ch_registered_static_object registered_object_t
Type of a registered object.
struct ch_objects_factory objects_factory_t
Type of the factory main object.
dyn_element_t * chFactoryDuplicateReference(dyn_element_t *dep)
Duplicates an object reference.
Definition chfactory.c:361
static dyn_element_t * dyn_list_find(const char *name, dyn_list_t *dlp)
Definition chfactory.c:144
registered_object_t * chFactoryRegisterObject(const char *name, void *objp)
Registers a generic object.
Definition chfactory.c:390
static dyn_element_t * dyn_find_object(const char *name, dyn_list_t *dlp)
Definition chfactory.c:294
dyn_buffer_t * chFactoryCreateBuffer(const char *name, size_t size)
Creates a generic dynamic buffer object.
Definition chfactory.c:509
dyn_pipe_t * chFactoryFindPipe(const char *name)
Retrieves a dynamic pipe object.
Definition chfactory.c:907
static void dyn_release_object_pool(dyn_element_t *dep, dyn_list_t *dlp, memory_pool_t *mp)
Definition chfactory.c:269
static void chFifoObjectInitAligned(objects_fifo_t *ofp, size_t objsize, size_t objn, unsigned objalign, void *objbuf, msg_t *msgbuf)
Initializes a FIFO object.
Definition chobjfifos.h:127
void chPipeObjectInit(pipe_t *pp, uint8_t *buf, size_t n)
Initializes a mailbox_t object.
Definition chpipes.c:206
void chSemObjectInit(semaphore_t *sp, cnt_t n)
Initializes a semaphore with the specified counter value.
Definition chsem.c:96
char name[CH_CFG_FACTORY_MAX_NAMES_LENGTH]
Definition chfactory.h:171
struct ch_dyn_element * next
Next dynamic object in the list.
Definition chfactory.h:165
ucnt_t refs
Number of references to this object.
Definition chfactory.h:169
dyn_element_t * next
Definition chfactory.h:181
mailbox_t mbx
The mailbox.
Definition chfactory.h:241
dyn_element_t element
List element of the dynamic buffer object.
Definition chfactory.h:237
dyn_element_t element
List element of the dynamic buffer object.
Definition chfactory.h:209
objects_fifo_t fifo
The objects FIFO.
Definition chfactory.h:257
dyn_element_t element
List element of the dynamic buffer object.
Definition chfactory.h:253
pipe_t pipe
The pipe.
Definition chfactory.h:273
dyn_element_t element
List element of the dynamic pipe object.
Definition chfactory.h:269
semaphore_t sem
The semaphore.
Definition chfactory.h:225
dyn_element_t element
List element of the dynamic semaphore.
Definition chfactory.h:221
void * objp
Pointer to the object.
Definition chfactory.h:197
dyn_element_t element
List element of the registered object.
Definition chfactory.h:192
Memory pool descriptor.
Definition chmempools.h:63