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