ChibiOS  21.6.0
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 
86 static 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 
98 static inline void dyn_list_init(dyn_list_t *dlp) {
99 
100  dlp->next = (dyn_element_t *)dlp;
101 }
102 
103 static 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 
116 static dyn_element_t *dyn_list_unlink(dyn_element_t *element,
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  /* Found.*/
124  prev->next = element->next;
125  return element;
126  }
127 
128  /* Next element in the list.*/
129  prev = prev->next;
130  }
131 
132  return NULL;
133 }
134 
135 #if CH_FACTORY_REQUIRES_HEAP || defined(__DOXYGEN__)
136 static dyn_element_t *dyn_create_object_heap(const char *name,
137  dyn_list_t *dlp,
138  size_t size,
139  unsigned align) {
140  dyn_element_t *dep;
141 
142  chDbgCheck(name != NULL);
143 
144  /* Checking if an object with this name has already been created.*/
145  dep = dyn_list_find(name, dlp);
146  if (dep != NULL) {
147  return NULL;
148  }
149 
150  /* Allocating space for the new buffer object.*/
151  dep = (dyn_element_t *)chHeapAllocAligned(NULL, size, align);
152  if (dep == NULL) {
153  return NULL;
154  }
155 
156  /* Initializing object list element.*/
157  copy_name(name, dep->name);
158  dep->refs = (ucnt_t)1;
159  dep->next = dlp->next;
160 
161  /* Updating factory list.*/
162  dlp->next = dep;
163 
164  return dep;
165 }
166 
167 static void dyn_release_object_heap(dyn_element_t *dep,
168  dyn_list_t *dlp) {
169 
170  chDbgCheck(dep != NULL);
171  chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
172 
173  dep->refs--;
174  if (dep->refs == (ucnt_t)0) {
175  dep = dyn_list_unlink(dep, dlp);
176  chHeapFree((void *)dep);
177  }
178 }
179 #endif /* CH_FACTORY_REQUIRES_HEAP */
180 
181 #if CH_FACTORY_REQUIRES_POOLS || defined(__DOXYGEN__)
182 static dyn_element_t *dyn_create_object_pool(const char *name,
183  dyn_list_t *dlp,
184  memory_pool_t *mp) {
185  dyn_element_t *dep;
186 
187  chDbgCheck(name != NULL);
188 
189  /* Checking if an object object with this name has already been created.*/
190  dep = dyn_list_find(name, dlp);
191  if (dep != NULL) {
192  return NULL;
193  }
194 
195  /* Allocating space for the new object.*/
196  dep = (dyn_element_t *)chPoolAlloc(mp);
197  if (dep == NULL) {
198  return NULL;
199  }
200 
201  /* Initializing object list element.*/
202  copy_name(name, dep->name);
203  dep->refs = (ucnt_t)1;
204  dep->next = dlp->next;
205 
206  /* Updating factory list.*/
207  dlp->next = (dyn_element_t *)dep;
208 
209  return dep;
210 }
211 
212 static void dyn_release_object_pool(dyn_element_t *dep,
213  dyn_list_t *dlp,
214  memory_pool_t *mp) {
215 
216  chDbgCheck(dep != NULL);
217  chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
218 
219  dep->refs--;
220  if (dep->refs == (ucnt_t)0) {
221  dep = dyn_list_unlink(dep, dlp);
222  chPoolFree(mp, (void *)dep);
223  }
224 }
225 #endif /* CH_FACTORY_REQUIRES_POOLS */
226 
227 static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) {
228  dyn_element_t *dep;
229 
230  chDbgCheck(name != NULL);
231 
232  /* Checking if an object with this name has already been created.*/
233  dep = dyn_list_find(name, dlp);
234  if (dep != NULL) {
235  /* Increasing references counter.*/
236  dep->refs++;
237  }
238 
239  return dep;
240 }
241 
242 /*===========================================================================*/
243 /* Module exported functions. */
244 /*===========================================================================*/
245 
246 /**
247  * @brief Initializes the objects factory.
248  *
249  * @init
250  */
251 void __factory_init(void) {
252 
253 #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
255 #else
256  chSemObjectInit(&ch_factory.sem, (cnt_t)1);
257 #endif
258 
259 #if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
260  dyn_list_init(&ch_factory.obj_list);
262  sizeof (registered_object_t),
264 #endif
265 #if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
266  dyn_list_init(&ch_factory.buf_list);
267 #endif
268 #if CH_CFG_FACTORY_SEMAPHORES == TRUE
269  dyn_list_init(&ch_factory.sem_list);
271  sizeof (dyn_semaphore_t),
273 #endif
274 #if CH_CFG_FACTORY_MAILBOXES == TRUE
275  dyn_list_init(&ch_factory.mbx_list);
276 #endif
277 #if CH_CFG_FACTORY_OBJ_FIFOS == TRUE
278  dyn_list_init(&ch_factory.fifo_list);
279 #endif
280 #if CH_CFG_FACTORY_PIPES == TRUE
281  dyn_list_init(&ch_factory.pipe_list);
282 #endif
283 }
284 
285 #if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
286 /**
287  * @brief Registers a generic object.
288  * @post A reference to the registered object is returned and the
289  * reference counter is initialized to one.
290  *
291  * @param[in] name name to be assigned to the registered object
292  * @param[in] objp pointer to the object to be registered
293  *
294  * @return The reference to the registered object.
295  * @retval NULL if the object to be registered cannot be allocated or
296  * a registered object with the same name exists.
297  *
298  * @api
299  */
301  void *objp) {
302  registered_object_t *rop;
303 
304  F_LOCK();
305 
306  rop = (registered_object_t *)dyn_create_object_pool(name,
309  if (rop != NULL) {
310  /* Initializing registered object data.*/
311  rop->objp = objp;
312  }
313 
314  F_UNLOCK();
315 
316  return rop;
317 }
318 
319 /**
320  * @brief Retrieves a registered object.
321  * @post A reference to the registered object is returned with the
322  * reference counter increased by one.
323  *
324  * @param[in] name name of the registered object
325  *
326  * @return The reference to the found registered object.
327  * @retval NULL if a registered object with the specified name
328  * does not exist.
329  *
330  * @api
331  */
333  registered_object_t *rop;
334 
335  F_LOCK();
336 
337  rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list);
338 
339  F_UNLOCK();
340 
341  return rop;
342 }
343 
344 /**
345  * @brief Retrieves a registered object by pointer.
346  * @post A reference to the registered object is returned with the
347  * reference counter increased by one.
348  *
349  * @param[in] objp pointer to the object to be retrieved
350  *
351  * @return The reference to the found registered object.
352  * @retval NULL if a registered object with the specified pointer
353  * does not exist.
354  *
355  * @api
356  */
359 
360  F_LOCK();
361 
362  while ((void *)rop != (void *)&ch_factory.obj_list) {
363  if (rop->objp == objp) {
364  rop->element.refs++;
365 
366  F_UNLOCK();
367 
368  return rop;
369  }
370  rop = (registered_object_t *)rop->element.next;
371  }
372 
373  F_UNLOCK();
374 
375  return NULL;
376 }
377 
378 /**
379  * @brief Releases a registered object.
380  * @details The reference counter of the registered object is decreased
381  * by one, if reaches zero then the registered object memory
382  * is freed.
383  * @note The object itself is not freed, it could be static, only the
384  * allocated list element is freed.
385  *
386  * @param[in] rop registered object reference
387  *
388  * @api
389  */
391 
392  F_LOCK();
393 
394  dyn_release_object_pool(&rop->element,
397 
398  F_UNLOCK();
399 }
400 #endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
401 
402 #if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
403 /**
404  * @brief Creates a generic dynamic buffer object.
405  * @post A reference to the dynamic buffer object is returned and the
406  * reference counter is initialized to one.
407  * @post The dynamic buffer object is filled with zeros.
408  *
409  * @param[in] name name to be assigned to the new dynamic buffer object
410  * @param[in] size payload size of the dynamic buffer object to be created
411  *
412  * @return The reference to the created dynamic buffer object.
413  * @retval NULL if the dynamic buffer object cannot be allocated or
414  * a dynamic buffer object with the same name exists.
415  *
416  * @api
417  */
418 dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
419  dyn_buffer_t *dbp;
420 
421  F_LOCK();
422 
423  dbp = (dyn_buffer_t *)dyn_create_object_heap(name,
425  sizeof (dyn_buffer_t) + size,
427  if (dbp != NULL) {
428  /* Initializing buffer object data.*/
429  memset((void *)(dbp + 1), 0, size);
430  }
431 
432  F_UNLOCK();
433 
434  return dbp;
435 }
436 
437 /**
438  * @brief Retrieves a dynamic buffer object.
439  * @post A reference to the dynamic buffer object is returned with the
440  * reference counter increased by one.
441  *
442  * @param[in] name name of the dynamic buffer object
443  *
444  * @return The reference to the found dynamic buffer object.
445  * @retval NULL if a dynamic buffer object with the specified name
446  * does not exist.
447  *
448  * @api
449  */
450 dyn_buffer_t *chFactoryFindBuffer(const char *name) {
451  dyn_buffer_t *dbp;
452 
453  F_LOCK();
454 
455  dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list);
456 
457  F_UNLOCK();
458 
459  return dbp;
460 }
461 
462 /**
463  * @brief Releases a dynamic buffer object.
464  * @details The reference counter of the dynamic buffer object is decreased
465  * by one, if reaches zero then the dynamic buffer object memory
466  * is freed.
467  *
468  * @param[in] dbp dynamic buffer object reference
469  *
470  * @api
471  */
473 
474  F_LOCK();
475 
476  dyn_release_object_heap(&dbp->element, &ch_factory.buf_list);
477 
478  F_UNLOCK();
479 }
480 #endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
481 
482 #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
483 /**
484  * @brief Creates a dynamic semaphore object.
485  * @post A reference to the dynamic semaphore object is returned and the
486  * reference counter is initialized to one.
487  * @post The dynamic semaphore object is initialized and ready to use.
488  *
489  * @param[in] name name to be assigned to the new dynamic semaphore object
490  * @param[in] n dynamic semaphore object counter initialization value
491  *
492  * @return The reference to the created dynamic semaphore object.
493  * @retval NULL if the dynamic semaphore object cannot be allocated or
494  * a dynamic semaphore with the same name exists.
495  *
496  * @api
497  */
499  dyn_semaphore_t *dsp;
500 
501  F_LOCK();
502 
503  dsp = (dyn_semaphore_t *)dyn_create_object_pool(name,
506  if (dsp != NULL) {
507  /* Initializing semaphore object dataa.*/
508  chSemObjectInit(&dsp->sem, n);
509  }
510 
511  F_UNLOCK();
512 
513  return dsp;
514 }
515 
516 /**
517  * @brief Retrieves a dynamic semaphore object.
518  * @post A reference to the dynamic semaphore object is returned with the
519  * reference counter increased by one.
520  *
521  * @param[in] name name of the dynamic semaphore object
522  *
523  * @return The reference to the found dynamic semaphore object.
524  * @retval NULL if a dynamic semaphore object with the specified name
525  * does not exist.
526  *
527  * @api
528  */
530  dyn_semaphore_t *dsp;
531 
532  F_LOCK();
533 
534  dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list);
535 
536  F_UNLOCK();
537 
538  return dsp;
539 }
540 
541 /**
542  * @brief Releases a dynamic semaphore object.
543  * @details The reference counter of the dynamic semaphore object is decreased
544  * by one, if reaches zero then the dynamic semaphore object memory
545  * is freed.
546  *
547  * @param[in] dsp dynamic semaphore object reference
548  *
549  * @api
550  */
552 
553  F_LOCK();
554 
555  dyn_release_object_pool(&dsp->element,
558 
559  F_UNLOCK();
560 }
561 #endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
562 
563 #if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXIGEN__)
564 /**
565  * @brief Creates a dynamic mailbox object.
566  * @post A reference to the dynamic mailbox object is returned and the
567  * reference counter is initialized to one.
568  * @post The dynamic mailbox object is initialized and ready to use.
569  *
570  * @param[in] name name to be assigned to the new dynamic mailbox object
571  * @param[in] n mailbox buffer size as number of messages
572  *
573  * @return The reference to the created dynamic mailbox object.
574  * @retval NULL if the dynamic mailbox object cannot be allocated or
575  * a dynamic mailbox object with the same name exists.
576  *
577  * @api
578  */
579 dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n) {
580  dyn_mailbox_t *dmp;
581 
582  F_LOCK();
583 
584  dmp = (dyn_mailbox_t *)dyn_create_object_heap(name,
586  sizeof (dyn_mailbox_t) +
587  (n * sizeof (msg_t)),
589  if (dmp != NULL) {
590  /* Initializing mailbox object data.*/
591  chMBObjectInit(&dmp->mbx, (msg_t *)(dmp + 1), n);
592  }
593 
594  F_UNLOCK();
595 
596  return dmp;
597 }
598 
599 /**
600  * @brief Retrieves a dynamic mailbox object.
601  * @post A reference to the dynamic mailbox object is returned with the
602  * reference counter increased by one.
603  *
604  * @param[in] name name of the dynamic mailbox object
605  *
606  * @return The reference to the found dynamic mailbox object.
607  * @retval NULL if a dynamic mailbox object with the specified name
608  * does not exist.
609  *
610  * @api
611  */
613  dyn_mailbox_t *dmp;
614 
615  F_LOCK();
616 
617  dmp = (dyn_mailbox_t *)dyn_find_object(name, &ch_factory.mbx_list);
618 
619  F_UNLOCK();
620 
621  return dmp;
622 }
623 
624 /**
625  * @brief Releases a dynamic mailbox object.
626  * @details The reference counter of the dynamic mailbox object is decreased
627  * by one, if reaches zero then the dynamic mailbox object memory
628  * is freed.
629  *
630  * @param[in] dmp dynamic mailbox object reference
631  *
632  * @api
633  */
635 
636  F_LOCK();
637 
638  dyn_release_object_heap(&dmp->element, &ch_factory.mbx_list);
639 
640  F_UNLOCK();
641 }
642 #endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */
643 
644 #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXIGEN__)
645 /**
646  * @brief Creates a dynamic "objects FIFO" object.
647  * @post A reference to the dynamic "objects FIFO" object is returned and
648  * the reference counter is initialized to one.
649  * @post The dynamic "objects FIFO" object is initialized and ready to use.
650  *
651  * @param[in] name name to be assigned to the new dynamic "objects FIFO"
652  * object
653  * @param[in] objsize size of objects
654  * @param[in] objn number of objects available
655  * @param[in] objalign required objects alignment
656  * @return The reference to the created dynamic "objects FIFO"
657  * object.
658  * @retval NULL if the dynamic "objects FIFO" object cannot be
659  * allocated or a dynamic "objects FIFO" object with
660  * the same name exists.
661  *
662  * @api
663  */
665  size_t objsize,
666  size_t objn,
667  unsigned objalign) {
668  size_t size1, size2;
669  dyn_objects_fifo_t *dofp;
670 
671  F_LOCK();
672 
673  /* Enforcing alignment for the objects array.*/
674  objsize = MEM_ALIGN_NEXT(objsize, objalign);
675  size1 = MEM_ALIGN_NEXT(sizeof (dyn_objects_fifo_t) + (objn * sizeof (msg_t)),
676  objalign);
677  size2 = objn * objsize;
678 
679  /* Allocating the FIFO object with messages buffer and objects buffer.*/
680  dofp = (dyn_objects_fifo_t *)dyn_create_object_heap(name,
682  size1 + size2,
683  objalign);
684  if (dofp != NULL) {
685  msg_t *msgbuf = (msg_t *)(dofp + 1);
686  uint8_t *objbuf = (uint8_t *)dofp + size1;
687 
688  /* Initializing mailbox object data.*/
689  chFifoObjectInitAligned(&dofp->fifo, objsize, objn, objalign,
690  (void *)objbuf, msgbuf);
691  }
692 
693  F_UNLOCK();
694 
695  return dofp;
696 }
697 
698 /**
699  * @brief Retrieves a dynamic "objects FIFO" object.
700  * @post A reference to the dynamic "objects FIFO" object is returned with
701  * the reference counter increased by one.
702  *
703  * @param[in] name name of the dynamic "objects FIFO" object
704  *
705  * @return The reference to the found dynamic "objects FIFO"
706  * object.
707  * @retval NULL if a dynamic "objects FIFO" object with the specified
708  * name does not exist.
709  *
710  * @api
711  */
713  dyn_objects_fifo_t *dofp;
714 
715  F_LOCK();
716 
717  dofp = (dyn_objects_fifo_t *)dyn_find_object(name, &ch_factory.fifo_list);
718 
719  F_UNLOCK();
720 
721  return dofp;
722 }
723 
724 /**
725  * @brief Releases a dynamic "objects FIFO" object.
726  * @details The reference counter of the dynamic "objects FIFO" object is
727  * decreased by one, if reaches zero then the dynamic "objects FIFO"
728  * object memory is freed.
729  *
730  * @param[in] dofp dynamic "objects FIFO" object reference
731  *
732  * @api
733  */
735 
736  F_LOCK();
737 
738  dyn_release_object_heap(&dofp->element, &ch_factory.fifo_list);
739 
740  F_UNLOCK();
741 }
742 #endif /* CH_CFG_FACTORY_OBJ_FIFOS = TRUE */
743 
744 #if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXIGEN__)
745 /**
746  * @brief Creates a dynamic pipe object.
747  * @post A reference to the dynamic pipe object is returned and
748  * the reference counter is initialized to one.
749  * @post The dynamic pipe object is initialized and ready to use.
750  *
751  * @param[in] name name to be assigned to the new dynamic pipe
752  * object
753  * @param[in] size pipe buffer size
754  * @return The reference to the created dynamic pipe
755  * object.
756  * @retval NULL if the dynamic pipe object cannot be
757  * allocated or a dynamic pipe object with
758  * the same name exists.
759  *
760  * @api
761  */
762 dyn_pipe_t *chFactoryCreatePipe(const char *name, size_t size) {
763  dyn_pipe_t *dpp;
764 
765  F_LOCK();
766 
767  dpp = (dyn_pipe_t *)dyn_create_object_heap(name,
769  sizeof (dyn_pipe_t) + size,
771  if (dpp != NULL) {
772  /* Initializing mailbox object data.*/
773  chPipeObjectInit(&dpp->pipe, (uint8_t *)(dpp + 1), size);
774  }
775 
776  F_UNLOCK();
777 
778  return dpp;
779 }
780 
781 /**
782  * @brief Retrieves a dynamic pipe object.
783  * @post A reference to the dynamic pipe object is returned with
784  * the reference counter increased by one.
785  *
786  * @param[in] name name of the pipe object
787  *
788  * @return The reference to the found dynamic pipe
789  * object.
790  * @retval NULL if a dynamic pipe object with the specified
791  * name does not exist.
792  *
793  * @api
794  */
795 dyn_pipe_t *chFactoryFindPipe(const char *name) {
796  dyn_pipe_t *dpp;
797 
798  F_LOCK();
799 
800  dpp = (dyn_pipe_t *)dyn_find_object(name, &ch_factory.pipe_list);
801 
802  F_UNLOCK();
803 
804  return dpp;
805 }
806 
807 /**
808  * @brief Releases a dynamic pipe object.
809  * @details The reference counter of the dynamic pipe object is
810  * decreased by one, if reaches zero then the dynamic pipe
811  * object memory is freed.
812  *
813  * @param[in] dpp dynamic pipe object reference
814  *
815  * @api
816  */
818 
819  F_LOCK();
820 
821  dyn_release_object_heap(&dpp->element, &ch_factory.pipe_list);
822 
823  F_UNLOCK();
824 }
825 #endif /* CH_CFG_FACTORY_PIPES = TRUE */
826 
827 #endif /* CH_CFG_USE_FACTORY == TRUE */
828 
829 /** @} */
chPoolObjectInit
static void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider)
Initializes an empty memory pool.
Definition: chmempools.h:189
chFactoryFindSemaphore
dyn_semaphore_t * chFactoryFindSemaphore(const char *name)
Retrieves a dynamic semaphore object.
Definition: chfactory.c:529
memory_pool_t
Memory pool descriptor.
Definition: chmempools.h:64
chFactoryFindMailbox
dyn_mailbox_t * chFactoryFindMailbox(const char *name)
Retrieves a dynamic mailbox object.
Definition: chfactory.c:612
chFactoryReleaseObjectsFIFO
void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp)
Releases a dynamic "objects FIFO" object.
Definition: chfactory.c:734
chPoolFree
void chPoolFree(memory_pool_t *mp, void *objp)
Releases an object into a memory pool.
Definition: chmempools.c:207
chFactoryCreateObjectsFIFO
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:664
ch_dyn_mailbox::element
dyn_element_t element
List element of the dynamic buffer object.
Definition: chfactory.h:245
ch_dyn_objects_fifo
Type of a dynamic buffer object.
Definition: chfactory.h:257
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:144
chFactoryFindPipe
dyn_pipe_t * chFactoryFindPipe(const char *name)
Retrieves a dynamic pipe object.
Definition: chfactory.c:795
CH_CFG_FACTORY_MAX_NAMES_LENGTH
#define CH_CFG_FACTORY_MAX_NAMES_LENGTH
Maximum length for object names.
Definition: rt/templates/chconf.h:496
ch_registered_static_object::objp
void * objp
Pointer to the object.
Definition: chfactory.h:205
ch_dyn_element
Type of a dynamic object list element.
Definition: chfactory.h:169
chFactoryRegisterObject
registered_object_t * chFactoryRegisterObject(const char *name, void *objp)
Registers a generic object.
Definition: chfactory.c:300
ch_dyn_objects_fifo::fifo
objects_fifo_t fifo
The objects FIFO.
Definition: chfactory.h:265
chHeapAllocAligned
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
chHeapFree
void chHeapFree(void *p)
Frees a previously allocated memory block.
Definition: chmemheaps.c:293
ch_dyn_list
Type of a dynamic object list.
Definition: chfactory.h:188
ch_dyn_object::element
dyn_element_t element
List element of the dynamic buffer object.
Definition: chfactory.h:217
msg_t
int32_t msg_t
Definition: chearly.h:88
chFactoryReleasePipe
void chFactoryReleasePipe(dyn_pipe_t *dpp)
Releases a dynamic pipe object.
Definition: chfactory.c:817
ch_dyn_semaphore
Type of a dynamic semaphore.
Definition: chfactory.h:225
chFactoryReleaseObject
void chFactoryReleaseObject(registered_object_t *rop)
Releases a registered object.
Definition: chfactory.c:390
chFactoryReleaseSemaphore
void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp)
Releases a dynamic semaphore object.
Definition: chfactory.c:551
ch_dyn_pipe
Type of a dynamic pipe object.
Definition: chfactory.h:273
ch_objects_factory::fifo_list
dyn_list_t fifo_list
List of the allocated "objects FIFO" objects.
Definition: chfactory.h:331
ucnt_t
uint32_t ucnt_t
Definition: chearly.h:93
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:118
ch_dyn_element::next
struct ch_dyn_element * next
Next dynamic object in the list.
Definition: chfactory.h:173
chFactoryFindObjectsFIFO
dyn_objects_fifo_t * chFactoryFindObjectsFIFO(const char *name)
Retrieves a dynamic "objects FIFO" object.
Definition: chfactory.c:712
ch_objects_factory::pipe_list
dyn_list_t pipe_list
List of the allocated pipe objects.
Definition: chfactory.h:337
CH_HEAP_ALIGNMENT
#define CH_HEAP_ALIGNMENT
Minimum alignment used for heap.
Definition: chmemheaps.h:42
chFactoryReleaseBuffer
void chFactoryReleaseBuffer(dyn_buffer_t *dbp)
Releases a dynamic buffer object.
Definition: chfactory.c:472
cnt_t
int32_t cnt_t
Definition: chearly.h:92
chSemObjectInit
void chSemObjectInit(semaphore_t *sp, cnt_t n)
Initializes a semaphore with the specified counter value.
Definition: rt/src/chsem.c:97
chFactoryReleaseMailbox
void chFactoryReleaseMailbox(dyn_mailbox_t *dmp)
Releases a dynamic mailbox object.
Definition: chfactory.c:634
chMtxObjectInit
void chMtxObjectInit(mutex_t *mp)
Initializes s mutex_t structure.
Definition: chmtx.c:103
ch_objects_factory::mtx
mutex_t mtx
Factory access mutex or semaphore.
Definition: chfactory.h:293
ch_dyn_semaphore::element
dyn_element_t element
List element of the dynamic semaphore.
Definition: chfactory.h:229
chMBObjectInit
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n)
Initializes a mailbox_t object.
Definition: chmboxes.c:87
ch_dyn_pipe::element
dyn_element_t element
List element of the dynamic pipe object.
Definition: chfactory.h:277
MEM_ALIGN_NEXT
#define MEM_ALIGN_NEXT(p, a)
Aligns to the next aligned memory address.
Definition: chalign.h:80
ch_dyn_object
Type of a dynamic buffer object.
Definition: chfactory.h:213
ch_dyn_mailbox
Type of a dynamic buffer object.
Definition: chfactory.h:241
ch_factory
objects_factory_t ch_factory
Factory object static instance.
Definition: chfactory.c:72
chFactoryCreateSemaphore
dyn_semaphore_t * chFactoryCreateSemaphore(const char *name, cnt_t n)
Creates a dynamic semaphore object.
Definition: chfactory.c:498
ch_dyn_element::refs
ucnt_t refs
Number of references to this object.
Definition: chfactory.h:177
chFactoryCreateBuffer
dyn_buffer_t * chFactoryCreateBuffer(const char *name, size_t size)
Creates a generic dynamic buffer object.
Definition: chfactory.c:418
chFactoryFindBuffer
dyn_buffer_t * chFactoryFindBuffer(const char *name)
Retrieves a dynamic buffer object.
Definition: chfactory.c:450
ch_objects_factory::buf_list
dyn_list_t buf_list
List of the allocated buffer objects.
Definition: chfactory.h:309
__factory_init
void __factory_init(void)
Initializes the objects factory.
Definition: chfactory.c:251
chFifoObjectInitAligned
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
ch_objects_factory
Type of the factory main object.
Definition: chfactory.h:288
ch_registered_static_object::element
dyn_element_t element
List element of the registered object.
Definition: chfactory.h:200
ch_objects_factory::sem_pool
memory_pool_t sem_pool
Pool of the available semaphores.
Definition: chfactory.h:319
ch_registered_static_object
Type of a registered object.
Definition: chfactory.h:196
chPipeObjectInit
void chPipeObjectInit(pipe_t *pp, uint8_t *buf, size_t n)
Initializes a mailbox_t object.
Definition: chpipes.c:207
ch_objects_factory::obj_pool
memory_pool_t obj_pool
Pool of the available registered objects.
Definition: chfactory.h:304
ch_dyn_pipe::pipe
pipe_t pipe
The pipe.
Definition: chfactory.h:281
chFactoryFindObject
registered_object_t * chFactoryFindObject(const char *name)
Retrieves a registered object.
Definition: chfactory.c:332
ch_dyn_objects_fifo::element
dyn_element_t element
List element of the dynamic buffer object.
Definition: chfactory.h:261
chPoolAlloc
void * chPoolAlloc(memory_pool_t *mp)
Allocates an object from a memory pool.
Definition: chmempools.c:161
ch_dyn_semaphore::sem
semaphore_t sem
The semaphore.
Definition: chfactory.h:233
chFactoryCreatePipe
dyn_pipe_t * chFactoryCreatePipe(const char *name, size_t size)
Creates a dynamic pipe object.
Definition: chfactory.c:762
chFactoryFindObjectByPointer
registered_object_t * chFactoryFindObjectByPointer(void *objp)
Retrieves a registered object by pointer.
Definition: chfactory.c:357
ch_objects_factory::obj_list
dyn_list_t obj_list
List of the registered objects.
Definition: chfactory.h:300
ch_objects_factory::mbx_list
dyn_list_t mbx_list
List of the allocated buffer objects.
Definition: chfactory.h:325
chCoreAllocAlignedI
static void * chCoreAllocAlignedI(size_t size, unsigned align)
Allocates a memory block.
Definition: chmemcore.h:150
chFactoryCreateMailbox
dyn_mailbox_t * chFactoryCreateMailbox(const char *name, size_t n)
Creates a dynamic mailbox object.
Definition: chfactory.c:579
ch_objects_factory::sem_list
dyn_list_t sem_list
List of the allocated semaphores.
Definition: chfactory.h:315
ch_dyn_mailbox::mbx
mailbox_t mbx
The mailbox.
Definition: chfactory.h:249