]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - packages/ti/ipc/ListMP.h
SDOCM00113338 fix: reduce number of Tasks for messageq_multi.c
[ipc/ipcdev.git] / packages / ti / ipc / ListMP.h
1 /*
2  * Copyright (c) 2012-2013, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /**
33  *  @file       ti/ipc/ListMP.h
34  *
35  *  @brief      Multiple processor shared memory list
36  *
37  *  @note       ListMP is currently only available for SYS/BIOS.
38  *
39  *  ListMP is a doubly linked-list based module designed to be used
40  *  in a multi-processor environment.  It provides a way for
41  *  multiple processors to create, access, and manipulate the same link
42  *  list in shared memory.
43  *
44  *  The ListMP module uses a NameServer instance
45  *  to store information about an instance during create.  Each
46  *  ListMP instance is created by specifying a name and region id.
47  *  The name supplied must be unique for all ListMP instances in the system.
48  *
49  *  ListMP_create() is used to create an instance of a ListMP.
50  *  Shared memory is modified during create.  Once created, an instance
51  *  may be opened by calling ListMP_open().  Open does not
52  *  modify any shared memory.  Open() should be called only when global
53  *  interrupts are enabled.
54  *
55  *  To use a ListMP instance, a #ListMP_Elem must be embedded
56  *  as the very first element of a structure.  ListMP does not provide
57  *  cache coherency for the buffer put onto the link list.
58  *  ListMP only provides cache coherency for the #ListMP_Elem
59  *  fields.  The buffer should be written back before being placed
60  *  on a ListMP, if cache coherency is required.
61  *
62  *  The ListMP header should be included in an application as follows:
63  *  @code
64  *  #include <ti/ipc/ListMP.h>
65  *  @endcode
66  */
68 #ifndef ti_ipc_ListMP__include
69 #define ti_ipc_ListMP__include
71 #include <ti/ipc/SharedRegion.h>
72 #include <ti/ipc/GateMP.h>
74 #if defined (__cplusplus)
75 extern "C" {
76 #endif
78 /* =============================================================================
79  *  All success and failure codes for the module
80  * =============================================================================
81  */
83 /*!
84  *  @brief  The resource is still in use
85  */
86 #define ListMP_S_BUSY            2
88 /*!
89  *  @brief  The module has been already setup
90  */
91 #define ListMP_S_ALREADYSETUP    1
93 /*!
94  *  @brief  Operation is successful.
95  */
96 #define ListMP_S_SUCCESS         0
98 /*!
99  *  @brief  Generic failure.
100  */
101 #define ListMP_E_FAIL           -1
103 /*!
104  *  @brief  Argument passed to function is invalid.
105  */
106 #define ListMP_E_INVALIDARG     -2
108 /*!
109  *  @brief  Operation resulted in memory failure.
110  */
111 #define ListMP_E_MEMORY         -3
113 /*!
114  *  @brief  The specified entity already exists.
115  */
116 #define ListMP_E_ALREADYEXISTS  -4
118 /*!
119  *  @brief  Unable to find the specified entity.
120  */
121 #define ListMP_E_NOTFOUND       -5
123 /*!
124  *  @brief  Operation timed out.
125  */
126 #define ListMP_E_TIMEOUT        -6
128 /*!
129  *  @brief  Module is not initialized.
130  */
131 #define ListMP_E_INVALIDSTATE   -7
133 /*!
134  *  @brief  A failure occurred in an OS-specific call
135  */
136 #define ListMP_E_OSFAILURE      -8
138 /*!
139  *  @brief  Specified resource is not available
140  */
141 #define ListMP_E_RESOURCE       -9
143 /*!
144  *  @brief  Operation was interrupted. Please restart the operation
145  */
146 #define ListMP_E_RESTART        -10
148 /* =============================================================================
149  *  Structures & Enums
150  * =============================================================================
151  */
153 /*!
154  *  @brief      ListMP_Handle type
155  */
156 typedef struct ListMP_Object *ListMP_Handle;
158 /*!
159  *  @brief  Structure defining a ListMP element.
160  */
161 typedef struct ListMP_Elem {
162     volatile SharedRegion_SRPtr next;
163     /*!< SharedRegion pointer to next element */
165     volatile SharedRegion_SRPtr prev;
166     /*!< SharedRegion pointer to previous element */
168 } ListMP_Elem;
170 /*!
171  *  @brief  Structure defining parameter structure for ListMP_create().
172  */
173 typedef struct ListMP_Params {
174     GateMP_Handle gate;
175     /*!< GateMP instance for critical region management of shared memory
176      *
177      *  Using the default value of NULL will result in use of the GateMP
178      *  system gate for context protection.
179      */
181     /*! @cond */
182     Ptr sharedAddr;
183     /*!< Physical address of the shared memory
184      *
185      *  The shared memory that will be used for maintaining shared state
186      *  information.  This is an optional parameter to create.  If value
187      *  is null, then the shared memory for the new instance will be
188      *  allocated from the heap in the specified region Id.
189      */
190     /*! @endcond */
192     String name;
193     /*!< Name of the instance
194      *
195      *  The name (if not NULL) must be unique among all ListMP
196      *  instances in the entire system.  When creating a new
197      *  heap, it is necessary to supply an instance name.
198      *
199      *  The name does not have to be persistent.  The supplied string is copied
200      *  into persistent memory.
201      */
203     UInt16 regionId;
204     /*!< SharedRegion ID.
205      *
206      *  The ID corresponding to the index of the shared region in which this
207      *  shared instance is to be placed.  This is used in create() only when
208      *  name is not null.
209      */
211 } ListMP_Params;
213 /* =============================================================================
214  *  ListMP Module-wide Functions
215  * =============================================================================
216  */
218 /*!
219  *  @brief      Initializes ListMP parameters.
220  *
221  *  @param      params  Instance param structure.
222  */
223 Void ListMP_Params_init(ListMP_Params *params);
225 /*!
226  *  @brief      Creates and initializes ListMP module.
227  *
228  *  @param      params  Instance param structure.
229  *
230  *  @return     ListMP instance handle.  NULL if create failed.
231  *
232  *  @sa         ListMP_delete()
233  */
234 ListMP_Handle ListMP_create(const ListMP_Params *params);
236 /*!
237  *  @brief      Close an opened ListMP instance
238  *
239  *  Closing an instance will free local memory consumed by the opened
240  *  instance.  Instances that are opened should be closed before the
241  *  instance is deleted.  If using NameServer,
242  *  the instance name will be removed from the NameServer instance.
243  *
244  *  @param      handlePtr  Pointer to a ListMP instance
245  *
246  *  @return     Status
247  *              - #ListMP_S_SUCCESS:  ListMP successfully closed
248  *              - #ListMP_E_FAIL:  A general failure has occurred
249  *
250  *  @sa         ListMP_open()
251  */
252 Int ListMP_close(ListMP_Handle *handlePtr);
254 /*!
255  *  @brief      Deletes a ListMP instance.
256  *
257  *  @param      handlePtr  Pointer to ListMP instance
258  *
259  *  @return     Status
260  *              - #ListMP_S_SUCCESS:  ListMP successfully deleted
261  *                  - #ListMP_E_FAIL:  ListMP delete failed
262  *
263  *  @sa         ListMP_create()
264  */
265 Int ListMP_delete(ListMP_Handle *handlePtr);
267 /*!
268  *  @brief      Open a created ListMP instance
269  *
270  *  An open can be performed on a previously created instance.
271  *  Open is used to gain access to the same ListMP instance.
272  *  Generally an instance is created on one processor and opened on
273  *  other processors but it can be opened on the same processor too.
274  *  Open returns a ListMP instance handle like create, but it does
275  *  not initialize any shared memory.
276  *
277  *  The open call searches the local ListMP NameServer table first
278  *  for a matching name. If no local match is found, it will search all
279  *  remote ListMP NameServer tables for a matching name.
280  *
281  *  A status value of #ListMP_S_SUCCESS is returned if a matching
282  *  ListMP instance is found.  A #ListMP_E_FAIL is returned if no
283  *  matching instance is found.  Generally this means the ListMP instance
284  *  has not yet been created.  A more specific status error is returned if
285  *  an error was raised.
286  *
287  *  Call close() when the opened instance is no longer needed.
288  *
289  *  @param      name        Name of created ListMP instance
290  *  @param      handlePtr   pointer to the handle if a handle was found.
291  *
292  *  @return     Status
293  *              - #ListMP_S_SUCCESS: ListMP successfully opened
294  *              - #ListMP_E_NOTFOUND: ListMP is not yet ready to be opened.
295  *              - #ListMP_E_FAIL: A general failure has occurred
296  *
297  *  @sa         ListMP_close()
298  *  @sa         ListMP_create()
299  */
300 Int ListMP_open(String name, ListMP_Handle *handlePtr);
302 /*! @cond
303  *  @brief      Open a created ListMP instance by address
304  *
305  *  Just like ListMP_open(), openByAddr returns a handle to a
306  *  created ListMP instance.  This function allows the ListMP to be
307  *  opened using a shared address instead of a name.
308  *  While ListMP_open() should generally be used to open ListMP
309  *  instances that have been either locally or remotely created, openByAddr
310  *  may be used to bypass a NameServer query that would typically be
311  *  required of an ListMP_open() call.
312  *
313  *  Opening by address requires that the created instance was created
314  *  by supplying a ListMP_Params#sharedAddr parameter rather than a
315  *  ListMP_Params#regionId parameter.
316  *
317  *  A status value of #ListMP_S_SUCCESS is returned if the ListMP is
318  *  successfully opened.  #ListMP_E_FAIL indicates that the ListMP is
319  *  not yet ready to be opened.
320  *
321  *  Call ListMP_close() when the opened instance is not longer needed.
322  *
323  *  @param      sharedAddr  Shared address for the ListMP instance
324  *  @param      handlePtr   Pointer to ListMP handle to be opened
325  *
326  *  @return     Status
327  *              - #ListMP_S_SUCCESS:  ListMP successfully opened
328  *              - #ListMP_E_FAIL:  ListMP is not ready to be opened
329  */
330 Int ListMP_openByAddr(Ptr sharedAddr, ListMP_Handle *handlePtr);
332 /*! @endcond */
334 /*! @cond
335  *  @brief      Amount of shared memory required for creation of each instance
336  *
337  *  The ListMP_Params#regionId or ListMP_Params#sharedAddr
338  *  needs to be supplied because the cache alignment settings for the region
339  *  may affect the total amount of shared memory required.
340  *
341  *  @param      params  Pointer to the parameters that will be used in
342  *                      the create.
343  *
344  *  @return     Number of MAUs needed to create the instance.
345  */
346 SizeT ListMP_sharedMemReq(const ListMP_Params *params);
348 /*! @endcond */
350 /* =============================================================================
351  *  ListMP Per-instance Functions
352  * =============================================================================
353  */
355 /*!
356  *  @brief      Determines if a ListMP instance is empty
357  *
358  *  @param      handle  a ListMP handle.
359  *
360  *  @return     TRUE if 'next' element points to head, otherwise FALSE
361  */
362 Bool ListMP_empty(ListMP_Handle handle);
364 /*!
365  *  @brief      Retrieves the GateMP handle associated with the ListMP instance.
366  *
367  *  @param      handle  a ListMP handle.
368  *
369  *  @return     GateMP handle for ListMP instance.
370  */
371 GateMP_Handle ListMP_getGate(ListMP_Handle handle);
373 /*!
374  *  @brief      Get an element from front of a ListMP instance
375  *
376  *  Atomically removes the element from the front of a
377  *  ListMP instance and returns a pointer to it.
378  *  Uses #ListMP_Params.gate for critical region management.
379  *
380  *  @param  handle  a ListMP handle.
381  *
382  *  @return     pointer to former first element. NULL if the ListMP is empty.
383  */
384 Ptr ListMP_getHead(ListMP_Handle handle);
386 /*!
387  *  @brief      Get an element from back of a ListMP instance
388  *
389  *  Atomically removes the element from the back of a
390  *  ListMP instance and returns a pointer to it.
391  *  Uses #ListMP_Params.gate for critical region management.
392  *
393  *  @param      handle  a ListMP handle.
394  *
395  *  @return     pointer to former last element.  NULL if the ListMP is empty.
396  */
397 Ptr ListMP_getTail(ListMP_Handle handle);
399 /*!
400  *  @brief      Insert an element into a ListMP instance
401  *
402  *  Atomically inserts @c newElem in the instance in front of @c curElem.
403  *  To place an element at the back of a ListMP instance, use
404  *  ListMP_putTail().  To place an element at the front of a
405  *  ListMP instance, use ListMP_putHead().
406  *
407  *  The following code shows an example.
408  *
409  *  @code
410  *  ListMP_Elem elem, curElem;
411  *
412  *  ListMP_insert(listHandle, &elem, &curElem);  // insert before curElem
413  *  @endcode
414  *
415  *  @param      handle  a ListMP handle.
416  *  @param      newElem  new element to insert into the ListMP.
417  *  @param      curElem  current element in the ListMP.
418  *
419  *  @return     Status
420  *              - #ListMP_S_SUCCESS:  if operation was successful
421  *              - #ListMP_E_FAIL:  if operation failed
422  */
423 Int ListMP_insert(ListMP_Handle handle,
424                   ListMP_Elem *newElem,
425                   ListMP_Elem *curElem);
427 /*!
428  *  @brief      Return the next element in a ListMP instance (non-atomic)
429  *
430  *  Is useful in searching a ListMP instance.
431  *  It does not remove any items from the ListMP instance.
432  *  The caller should protect the ListMP instance from being changed
433  *  while using this call since it is non-atomic.
434  *
435  *  To look at the first `elem` on the ListMP, use NULL as the `elem`
436  *  argument.
437  *
438  *  The following code shows an example.
439  *  The scanning of a ListMP instance should be protected
440  *  against other threads that modify the ListMP.
441  *
442  *  @code
443  *  ListMP_Elem   *elem = NULL;
444  *  GateMP_Handle gate;
445  *  IArg          key;
446  *
447  *  // get the gate for the ListMP instance
448  *  gate = ListMP_getGate(listHandle);
449  *
450  *  // Begin protection against modification of the ListMP.
451  *  key = GateMP_enter(gate);
452  *
453  *  while ((elem = ListMP_next(ListMPHandle, elem)) != NULL) {
454  *      //act on elem as needed. For example call ListMP_remove().
455  *  }
456  *
457  *  // End protection against modification of the ListMP.
458  *  GateMP_leave(gate, key);
459  *  @endcode
460  *
461  *  @param      handle  a ListMP handle.
462  *  @param      elem    element in ListMP or NULL to start at the head
463  *
464  *  @return     next element in ListMP instance or NULL to denote end.
465  */
466 Ptr ListMP_next(ListMP_Handle handle, ListMP_Elem *elem);
468 /*!
469  *  @brief      Return the previous element in ListMP instance (non-atomic)
470  *
471  *  Useful in searching a ListMP instance in reverse order.
472  *  It does not remove any items from the ListMP instance.
473  *  The caller should protect the ListMP instance from being changed
474  *  while using this call since it is non-atomic.
475  *
476  *  To look at the last `elem` on the ListMP instance, use NULL as the
477  *  `elem` argument.
478  *
479  *  The following code shows an example. The scanning of a ListMP instance
480  *  should be protected against other threads that modify the instance.
481  *
482  *  @code
483  *  ListMP_Elem  *elem = NULL;
484  *  GateMP_Handle gate;
485  *  IArg          key;
486  *
487  *  // get the gate for the ListMP instance
488  *  gate = ListMP_getGate(listHandle);
489  *
490  *  // Begin protection against modification of the ListMP.
491  *  key = GateMP_enter(gate);
492  *
493  *  while ((elem = ListMP_prev(listHandle, elem)) != NULL) {
494  *      //act on elem as needed. For example call ListMP_remove().
495  *  }
496  *
497  *  // End protection against modification of the ListMP.
498  *  GateMP_leave(gate, key);
499  *  @endcode
500  *
501  *  @param      handle  a ListMP handle.
502  *  @param      elem    element in ListMP or NULL to start at the end
503  *
504  *  @return     previous element in ListMP or NULL if empty.
505  */
506 Ptr ListMP_prev(ListMP_Handle handle, ListMP_Elem *elem);
508 /*!
509  *  @brief      Put an element at head of a ListMP instance
510  *
511  *  Atomically places the element at the front of a ListMP instance.
512  *  Uses #ListMP_Params.gate for critical region management.
513  *
514  *  @param      handle  a ListMP handle
515  *  @param      elem    pointer to new ListMP element
516  *
517  *  @return     Status
518  *              - #ListMP_S_SUCCESS:  if operation was successful
519  *              - #ListMP_E_FAIL:  if operation failed
520  */
521 Int ListMP_putHead(ListMP_Handle handle, ListMP_Elem *elem);
523 /*!
524  *  @brief      Put an element at back of a ListMP instance
525  *
526  *  Atomically places the element at the back of a ListMP instance.
527  *  Uses #ListMP_Params.gate for critical region management.
528  *
529  *  @param      handle  a ListMP handle
530  *  @param      elem    pointer to new ListMP element
531  *
532  *  @return     Status
533  *              - #ListMP_S_SUCCESS:  if operation was successful
534  *              - #ListMP_E_FAIL:  if operation failed
535  */
536 Int ListMP_putTail(ListMP_Handle handle, ListMP_Elem *elem);
538 /*!
539  *  @brief      Remove an element from a ListMP instance
540  *
541  *  Atomically removes an element from a ListMP.
542  *
543  *  The @c elem parameter is a pointer to an existing element to be removed
544  *  from a ListMP instance.
545  *
546  *  @param      handle  a ListMP handle
547  *  @param      elem    element in ListMP
548  *
549  *  @return     Status
550  *              - #ListMP_S_SUCCESS:  if operation was successful
551  *              - #ListMP_E_FAIL:  if operation failed
552  */
553 Int ListMP_remove(ListMP_Handle handle, ListMP_Elem *elem);
555 #if defined (__cplusplus)
557 #endif /* defined (__cplusplus) */
559 #endif /* ti_ipc_ListMP__include */