Helixis 1.0
Task Programming API
sources/liblfds/freelist/freelist_pop_push.c
Go to the documentation of this file.
00001 #include "freelist_internal.h"
00002 #if defined(HLX_BUILD_WITH_PARALLEL_THREADING)
00003 
00004 extern hlx_api gl_api;
00005 
00006 /****************************************************************************/
00007 struct freelist_element *freelist_pop( struct freelist_state *fs, struct freelist_element **fe )
00008 {
00009   ALIGN(ALIGN_DOUBLE_POINTER) struct freelist_element
00010     *fe_local[FREELIST_PAC_SIZE];
00011 
00012   fe_local[FREELIST_COUNTER] = fs->top[FREELIST_COUNTER];
00013   fe_local[FREELIST_POINTER] = fs->top[FREELIST_POINTER];
00014 
00015   /* TRD : note that abstraction_dcas loads the original value of the destination (fs->top) into the compare (fe_local)
00016            (this happens of course after the CAS itself has occurred inside abstraction_dcas)
00017   */
00018 
00019   do
00020   {
00021     if( fe_local[FREELIST_POINTER] == 0 )
00022     {
00023       *fe = 0;
00024       return( *fe );
00025     }
00026   }
00027   while( 0 == gl_api.atomic_dcas_entry((volatile atom_t *) fs->top, (atom_t *) fe_local[FREELIST_POINTER]->next, (atom_t *) fe_local) );
00028 
00029   *fe = (struct freelist_element *) fe_local[FREELIST_POINTER];
00030 
00031   return( *fe );
00032 }
00033 
00034 
00035 
00036 
00037 
00038 /****************************************************************************/
00039 struct freelist_element *freelist_guaranteed_pop( struct freelist_state *fs, struct freelist_element **fe )
00040 {
00041 
00042   freelist_internal_new_element( fs, fe );
00043 
00044   return( *fe );
00045 }
00046 
00047 
00048 
00049 
00050 
00051 /****************************************************************************/
00052 void freelist_push( struct freelist_state *fs, struct freelist_element *fe )
00053 {
00054   ALIGN(ALIGN_DOUBLE_POINTER) struct freelist_element
00055     *fe_local[FREELIST_PAC_SIZE],
00056     *original_fe_next[FREELIST_PAC_SIZE];
00057 
00058   fe_local[FREELIST_POINTER] = fe;
00059   fe_local[FREELIST_COUNTER] = (struct freelist_element *) gl_api.atomic_incr_entry( (atom_t *) &fs->aba_counter );
00060 
00061   original_fe_next[FREELIST_POINTER] = fs->top[FREELIST_POINTER];
00062   original_fe_next[FREELIST_COUNTER] = fs->top[FREELIST_COUNTER];
00063 
00064   /* TRD : note that abstraction_dcas loads the original value of the destination (fs->top) into the compare (original_fe_next)
00065            (this happens of course after the CAS itself has occurred inside abstraction_dcas)
00066            this then causes us in our loop, should we repeat it, to update fe_local->next to a more
00067            up-to-date version of the head of the freelist
00068   */
00069 
00070   do
00071   {
00072     fe_local[FREELIST_POINTER]->next[FREELIST_POINTER] = original_fe_next[FREELIST_POINTER];
00073     fe_local[FREELIST_POINTER]->next[FREELIST_COUNTER] = original_fe_next[FREELIST_COUNTER];
00074   }
00075   while( 0 == gl_api.atomic_dcas_entry((volatile atom_t *) fs->top, (atom_t *) fe_local, (atom_t *) original_fe_next) );
00076 
00077   return;
00078 }
00079 
00080 #endif /* !HLX_BUILD_WITH_PARALLEL_THREADING */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines