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