openmpi  3.1.6
About: Open MPI is a high performance Message Passing Interface (MPI) library project combining technologies and resources from several other projects (FT-MPI, LA-MPI, LAM/MPI, and PACX-MPI) in order to build the best MPI library available. 3.x series.
  Fossies Dox: openmpi-3.1.6.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

opal_list.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3  * University Research and Technology
4  * Corporation. All rights reserved.
5  * Copyright (c) 2004-2006 The University of Tennessee and The University
6  * of Tennessee Research Foundation. All rights
7  * reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  * University of Stuttgart. All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  * All rights reserved.
12  * Copyright (c) 2007 Voltaire All rights reserved.
13  * Copyright (c) 2013 Los Alamos National Security, LLC. All rights
14  * reserved.
15  * Copyright (c) 2016 Research Organization for Information Science
16  * and Technology (RIST). All rights reserved.
17  * $COPYRIGHT$
18  *
19  * Additional copyrights may follow
20  *
21  * $HEADER$
22  */
67 #ifndef OPAL_LIST_H
68 #define OPAL_LIST_H
69 
70 #include "opal_config.h"
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include "opal/class/opal_object.h"
74 
75 #if OPAL_ENABLE_DEBUG
76 /* Need atomics for debugging (reference counting) */
77 #include "opal/sys/atomic.h"
78 #include "opal/threads/mutex.h"
79 #endif
80 
82 
95 
96 
103 {
106  volatile struct opal_list_item_t * volatile opal_list_next;
108  volatile struct opal_list_item_t * volatile opal_list_prev;
110  int32_t item_free;
111 
112 #if OPAL_ENABLE_DEBUG
113 
114  volatile int32_t opal_list_item_refcount;
116  volatile struct opal_list_t* opal_list_item_belong_to;
117 #endif
118 };
122 typedef struct opal_list_item_t opal_list_item_t;
123 
124 
132 #define opal_list_get_next(item) \
133  ((item) ? ((opal_list_item_t*) ((opal_list_item_t*)(item))->opal_list_next) : NULL)
134 
142 #define opal_list_get_prev(item) \
143  ((item) ? ((opal_list_item_t*) ((opal_list_item_t*)(item))->opal_list_prev) : NULL)
144 
145 
152 {
157  volatile size_t opal_list_length;
159 };
163 typedef struct opal_list_t opal_list_t;
164 
173 #define OPAL_LIST_DESTRUCT(list) \
174  do { \
175  opal_list_item_t *it; \
176  if (1 == ((opal_object_t*)(list))->obj_reference_count) { \
177  while (NULL != (it = opal_list_remove_first(list))) { \
178  OBJ_RELEASE(it); \
179  } \
180  } \
181  OBJ_DESTRUCT(list); \
182  } while(0);
183 
184 #define OPAL_LIST_RELEASE(list) \
185  do { \
186  opal_list_item_t *it; \
187  if (1 == ((opal_object_t*)(list))->obj_reference_count) { \
188  while (NULL != (it = opal_list_remove_first(list))) { \
189  OBJ_RELEASE(it); \
190  } \
191  } \
192  OBJ_RELEASE(list); \
193  } while(0);
194 
195 
213 #define OPAL_LIST_FOREACH(item, list, type) \
214  for (item = (type *) (list)->opal_list_sentinel.opal_list_next ; \
215  item != (type *) &(list)->opal_list_sentinel ; \
216  item = (type *) ((opal_list_item_t *) (item))->opal_list_next)
217 
235 #define OPAL_LIST_FOREACH_REV(item, list, type) \
236  for (item = (type *) (list)->opal_list_sentinel.opal_list_prev ; \
237  item != (type *) &(list)->opal_list_sentinel ; \
238  item = (type *) ((opal_list_item_t *) (item))->opal_list_prev)
239 
259 #define OPAL_LIST_FOREACH_SAFE(item, next, list, type) \
260  for (item = (type *) (list)->opal_list_sentinel.opal_list_next, \
261  next = (type *) ((opal_list_item_t *) (item))->opal_list_next ;\
262  item != (type *) &(list)->opal_list_sentinel ; \
263  item = next, next = (type *) ((opal_list_item_t *) (item))->opal_list_next)
264 
284 #define OPAL_LIST_FOREACH_SAFE_REV(item, prev, list, type) \
285  for (item = (type *) (list)->opal_list_sentinel.opal_list_prev, \
286  prev = (type *) ((opal_list_item_t *) (item))->opal_list_prev ;\
287  item != (type *) &(list)->opal_list_sentinel ; \
288  item = prev, prev = (type *) ((opal_list_item_t *) (item))->opal_list_prev)
289 
290 
303 static inline bool opal_list_is_empty(opal_list_t* list)
304 {
305  return (list->opal_list_sentinel.opal_list_next ==
306  &(list->opal_list_sentinel) ? true : false);
307 }
308 
309 
325 {
327 #if OPAL_ENABLE_DEBUG
328  /* Spot check: ensure that the first item is only on one list */
329 
330  assert(1 == item->opal_list_item_refcount);
331  assert( list == item->opal_list_item_belong_to );
332 #endif
333 
334  return item;
335 }
336 
352 {
354 #if OPAL_ENABLE_DEBUG
355  /* Spot check: ensure that the last item is only on one list */
356 
357  assert( 1 == item->opal_list_item_refcount );
358  assert( list == item->opal_list_item_belong_to );
359 #endif
360 
361  return item;
362 }
363 
382 {
383  return &(list->opal_list_sentinel);
384 }
385 
404 {
405  return &(list->opal_list_sentinel);
406 }
407 
408 
428 static inline size_t opal_list_get_size(opal_list_t* list)
429 {
430 #if OPAL_ENABLE_DEBUG && 0
431  /* not sure if we really want this running in devel, as it does
432  * slow things down. Wanted for development of splice / join to
433  * make sure length was reset properly
434  */
435  size_t check_len = 0;
436  opal_list_item_t *item;
437 
438  for (item = opal_list_get_first(list) ;
439  item != opal_list_get_end(list) ;
440  item = opal_list_get_next(item)) {
441  check_len++;
442  }
443 
444  if (check_len != list->opal_list_length) {
445  fprintf(stderr," Error :: opal_list_get_size - opal_list_length does not match actual list length\n");
446  fflush(stderr);
447  abort();
448  }
449 #endif
450 
451  return list->opal_list_length;
452 }
453 
454 
477  (opal_list_t *list, opal_list_item_t *item)
478 {
479 #if OPAL_ENABLE_DEBUG
480  opal_list_item_t *item_ptr;
481  bool found = false;
482 
483  /* check to see that the item is in the list */
484  for (item_ptr = opal_list_get_first(list);
485  item_ptr != opal_list_get_end(list);
486  item_ptr = (opal_list_item_t *)(item_ptr->opal_list_next)) {
487  if (item_ptr == (opal_list_item_t *) item) {
488  found = true;
489  break;
490  }
491  }
492  if (!found) {
493  fprintf(stderr," Warning :: opal_list_remove_item - the item %p is not on the list %p \n",(void*) item, (void*) list);
494  fflush(stderr);
495  return (opal_list_item_t *)NULL;
496  }
497 
498  assert( list == item->opal_list_item_belong_to );
499 #endif
500 
501  /* reset next pointer of previous element */
503 
504  /* reset previous pointer of next element */
506 
507  list->opal_list_length--;
508 
509 #if OPAL_ENABLE_DEBUG
510  /* Spot check: ensure that this item is still only on one list */
511 
512  OPAL_THREAD_ADD32( &(item->opal_list_item_refcount), -1 );
513  assert(0 == item->opal_list_item_refcount);
514  item->opal_list_item_belong_to = NULL;
515 #endif
516 
517  return (opal_list_item_t *)item->opal_list_prev;
518 }
519 
520 
535 #if OPAL_ENABLE_DEBUG
536 #define opal_list_append(l,i) \
537 _opal_list_append(l,i,__FILE__,__LINE__)
538 #else
539 #define opal_list_append(l,i) \
540 _opal_list_append(l,i)
541 #endif /* OPAL_ENABLE_DEBUG */
542 
543 static inline void _opal_list_append(opal_list_t *list, opal_list_item_t *item
544 #if OPAL_ENABLE_DEBUG
545  , const char* FILE_NAME, int LINENO
546 #endif /* OPAL_ENABLE_DEBUG */
547  )
548 {
549  opal_list_item_t* sentinel = &(list->opal_list_sentinel);
550 #if OPAL_ENABLE_DEBUG
551  /* Spot check: ensure that this item is previously on no lists */
552 
553  assert(0 == item->opal_list_item_refcount);
554  assert( NULL == item->opal_list_item_belong_to );
555  item->super.cls_init_file_name = FILE_NAME;
556  item->super.cls_init_lineno = LINENO;
557 #endif
558 
559  /* set new element's previous pointer */
560  item->opal_list_prev = sentinel->opal_list_prev;
561 
562  /* reset previous pointer on current last element */
563  sentinel->opal_list_prev->opal_list_next = item;
564 
565  /* reset new element's next pointer */
566  item->opal_list_next = sentinel;
567 
568  /* reset the list's tail element previous pointer */
569  sentinel->opal_list_prev = item;
570 
571  /* increment list element counter */
572  list->opal_list_length++;
573 
574 #if OPAL_ENABLE_DEBUG
575  /* Spot check: ensure this item is only on the list that we just
576  appended it to */
577 
578  OPAL_THREAD_ADD32( &(item->opal_list_item_refcount), 1 );
579  assert(1 == item->opal_list_item_refcount);
580  item->opal_list_item_belong_to = list;
581 #endif
582 }
583 
584 
598 static inline void opal_list_prepend(opal_list_t *list,
599  opal_list_item_t *item)
600 {
601  opal_list_item_t* sentinel = &(list->opal_list_sentinel);
602 #if OPAL_ENABLE_DEBUG
603  /* Spot check: ensure that this item is previously on no lists */
604 
605  assert(0 == item->opal_list_item_refcount);
606  assert( NULL == item->opal_list_item_belong_to );
607 #endif
608 
609  /* reset item's next pointer */
610  item->opal_list_next = sentinel->opal_list_next;
611 
612  /* reset item's previous pointer */
613  item->opal_list_prev = sentinel;
614 
615  /* reset previous first element's previous poiner */
616  sentinel->opal_list_next->opal_list_prev = item;
617 
618  /* reset head's next pointer */
619  sentinel->opal_list_next = item;
620 
621  /* increment list element counter */
622  list->opal_list_length++;
623 
624 #if OPAL_ENABLE_DEBUG
625  /* Spot check: ensure this item is only on the list that we just
626  prepended it to */
627 
628  OPAL_THREAD_ADD32( &(item->opal_list_item_refcount), 1 );
629  assert(1 == item->opal_list_item_refcount);
630  item->opal_list_item_belong_to = list;
631 #endif
632 }
633 
634 
652 {
653  /* Removes and returns first item on list.
654  Caller now owns the item and should release the item
655  when caller is done with it.
656  */
657  volatile opal_list_item_t *item;
658  if ( 0 == list->opal_list_length ) {
659  return (opal_list_item_t *)NULL;
660  }
661 
662 #if OPAL_ENABLE_DEBUG
663  /* Spot check: ensure that the first item is only on this list */
664 
665  assert(1 == list->opal_list_sentinel.opal_list_next->opal_list_item_refcount);
666 #endif
667 
668  /* reset list length counter */
669  list->opal_list_length--;
670 
671  /* get pointer to first element on the list */
672  item = list->opal_list_sentinel.opal_list_next;
673 
674  /* reset previous pointer of next item on the list */
676 
677  /* reset the head next pointer */
679 
680 #if OPAL_ENABLE_DEBUG
681  assert( list == item->opal_list_item_belong_to );
682  item->opal_list_item_belong_to = NULL;
685 
686  /* Spot check: ensure that the item we're returning is now on no
687  lists */
688 
689  OPAL_THREAD_ADD32( &(item->opal_list_item_refcount), -1 );
690  assert(0 == item->opal_list_item_refcount);
691 #endif
692 
693  return (opal_list_item_t *) item;
694 }
695 
696 
714 {
715  /* Removes, releases and returns last item on list.
716  Caller now owns the item and should release the item
717  when caller is done with it.
718  */
719  volatile opal_list_item_t *item;
720  if ( 0 == list->opal_list_length ) {
721  return (opal_list_item_t *)NULL;
722  }
723 
724 #if OPAL_ENABLE_DEBUG
725  /* Spot check: ensure that the first item is only on this list */
726 
727  assert(1 == list->opal_list_sentinel.opal_list_prev->opal_list_item_refcount);
728 #endif
729 
730  /* reset list length counter */
731  list->opal_list_length--;
732 
733  /* get item */
734  item = list->opal_list_sentinel.opal_list_prev;
735 
736  /* reset previous pointer on next to last pointer */
738 
739  /* reset tail's previous pointer */
741 
742 #if OPAL_ENABLE_DEBUG
743  assert( list == item->opal_list_item_belong_to );
745 
746  /* Spot check: ensure that the item we're returning is now on no
747  lists */
748 
749  OPAL_THREAD_ADD32( &(item->opal_list_item_refcount), -1 );
750  assert(0 == item->opal_list_item_refcount);
751  item->opal_list_item_belong_to = NULL;
752 #endif
753 
754  return (opal_list_item_t *) item;
755 }
756 
766 static inline void opal_list_insert_pos(opal_list_t *list, opal_list_item_t *pos,
767  opal_list_item_t *item)
768 {
769 #if OPAL_ENABLE_DEBUG
770  /* Spot check: ensure that the item we're insertting is currently
771  not on any list */
772 
773  assert(0 == item->opal_list_item_refcount);
774  assert( NULL == item->opal_list_item_belong_to );
775 #endif
776 
777  /* point item at the existing elements */
778  item->opal_list_next = pos;
779  item->opal_list_prev = pos->opal_list_prev;
780 
781  /* splice into the list */
782  pos->opal_list_prev->opal_list_next = item;
783  pos->opal_list_prev = item;
784 
785  /* reset list length counter */
786  list->opal_list_length++;
787 
788 #if OPAL_ENABLE_DEBUG
789  /* Spot check: double check that this item is only on the list
790  that we just added it to */
791 
792  OPAL_THREAD_ADD32( &(item->opal_list_item_refcount), 1 );
793  assert(1 == item->opal_list_item_refcount);
794  item->opal_list_item_belong_to = list;
795 #endif
796 }
797 
817  long long idx);
818 
819 
838  opal_list_t *xlist);
839 
840 
867 
889  opal_list_item_t **b);
890 
912 
914 
915 #endif /* OPAL_LIST_H */
opal_list_t::opal_list_length
volatile size_t opal_list_length
Quick reference to the number of items in the list.
Definition: opal_list.h:157
opal_list_get_next
#define opal_list_get_next(item)
Get the next item in a list.
Definition: opal_list.h:132
opal_list_splice
OPAL_DECLSPEC void opal_list_splice(opal_list_t *thislist, opal_list_item_t *pos, opal_list_t *xlist, opal_list_item_t *first, opal_list_item_t *last)
Splice a list into another list.
Definition: opal_list.c:206
opal_list_t::super
opal_object_t super
Generic parent class for all Open MPI objects.
Definition: opal_list.h:153
opal_list_remove_last
static opal_list_item_t * opal_list_remove_last(opal_list_t *list)
Remove the last item from the list and return it.
Definition: opal_list.h:713
opal_list_get_first
static opal_list_item_t * opal_list_get_first(opal_list_t *list)
Return the first item on the list (does not remove it).
Definition: opal_list.h:324
opal_list_remove_first
static opal_list_item_t * opal_list_remove_first(opal_list_t *list)
Remove the first item from the list and return it.
Definition: opal_list.h:651
first
static bool first
Definition: ess_hnp_module.c:955
mutex.h
opal_list_insert_pos
static void opal_list_insert_pos(opal_list_t *list, opal_list_item_t *pos, opal_list_item_t *item)
Add an item to the list before a given element.
Definition: opal_list.h:766
_opal_list_append
static void _opal_list_append(opal_list_t *list, opal_list_item_t *item)
Definition: opal_list.h:543
BEGIN_C_DECLS
#define BEGIN_C_DECLS
code that should be in ompi_config_bottom.h regardless of build status
Definition: opal_config_bottom.h:85
abort
bool abort
Definition: orted_main.c:136
OBJ_CLASS_DECLARATION
BEGIN_C_DECLS OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_list_t)
opal_list_join
OPAL_DECLSPEC void opal_list_join(opal_list_t *thislist, opal_list_item_t *pos, opal_list_t *xlist)
Join a list into another list.
Definition: opal_list.c:191
opal_object_t
Base object.
Definition: opal_object.h:194
opal_list_prepend
static void opal_list_prepend(opal_list_t *list, opal_list_item_t *item)
Prepend an item to the beginning of the list.
Definition: opal_list.h:598
opal_object.h
opal_list_get_end
static opal_list_item_t * opal_list_get_end(opal_list_t *list)
Return the end of the list; an invalid list entry suitable for comparison only.
Definition: opal_list.h:403
opal_list_item_t::opal_list_prev
volatile struct opal_list_item_t *volatile opal_list_prev
Pointer to previous list item.
Definition: opal_list.h:108
last
static struct timeval current last
Definition: ess_hnp_module.c:954
opal_list_insert
OPAL_DECLSPEC bool opal_list_insert(opal_list_t *list, opal_list_item_t *item, long long idx)
Add an item to the list at a specific index location in the list.
Definition: opal_list.c:112
opal_list_item_t::item_free
int32_t item_free
Definition: opal_list.h:110
OPAL_THREAD_ADD32
#define OPAL_THREAD_ADD32
Definition: thread_usage.h:152
opal_list_sort
OPAL_DECLSPEC int opal_list_sort(opal_list_t *list, opal_list_item_compare_fn_t compare)
Sort a list with a provided compare function.
Definition: opal_list.c:231
OPAL_DECLSPEC
#define OPAL_DECLSPEC
Definition: opal_config_bottom.h:253
opal_list_item_t
Definition: opal_list.h:103
opal_list_get_begin
static opal_list_item_t * opal_list_get_begin(opal_list_t *list)
Return the beginning of the list; an invalid list entry suitable for comparison only.
Definition: opal_list.h:381
opal_list_item_t::super
opal_object_t super
Generic parent class for all Open MPI objects.
Definition: opal_list.h:104
opal_list_is_empty
static bool opal_list_is_empty(opal_list_t *list)
Check for empty list.
Definition: opal_list.h:303
opal_list_get_last
static opal_list_item_t * opal_list_get_last(opal_list_t *list)
Return the last item on the list (does not remove it).
Definition: opal_list.h:351
opal_list_t::opal_list_sentinel
opal_list_item_t opal_list_sentinel
Head and tail item of the list.
Definition: opal_list.h:155
opal_list_t
Definition: opal_list.h:152
atomic.h
opal_list_item_t::opal_list_next
volatile struct opal_list_item_t *volatile opal_list_next
Pointer to next list item.
Definition: opal_list.h:106
opal_list_remove_item
static opal_list_item_t * opal_list_remove_item(opal_list_t *list, opal_list_item_t *item)
Remove an item from a list.
Definition: opal_list.h:477
END_C_DECLS
#define END_C_DECLS
Definition: opal_config_bottom.h:86
NULL
#define NULL
Copyright (C) 2000-2004 by Etnus, LLC.
Definition: ompi_msgq_dll.c:136
opal_list_get_size
static size_t opal_list_get_size(opal_list_t *list)
Return the number of items in a list.
Definition: opal_list.h:428
opal_list_item_compare_fn_t
int(* opal_list_item_compare_fn_t)(opal_list_item_t **a, opal_list_item_t **b)
Comparison function for opal_list_sort(), below.
Definition: opal_list.h:888