win-pvdrivers

view liblfds.6/src/single_dir_for_windows_kernel/freelist_pop_push.c @ 1025:aa2e51f67f7c

Fix hibernate under Win8. Change debugprints.
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:14:53 2013 +1100 (2013-02-19)
parents 6300617040e0
children
line source
1 #include "freelist_internal.h"
7 /****************************************************************************/
8 struct freelist_element *freelist_pop( struct freelist_state *fs, struct freelist_element **fe )
9 {
10 ALIGN(ALIGN_DOUBLE_POINTER) struct freelist_element
11 *fe_local[FREELIST_PAC_SIZE];
13 assert( fs != NULL );
14 assert( fe != NULL );
16 fe_local[FREELIST_COUNTER] = fs->top[FREELIST_COUNTER];
17 fe_local[FREELIST_POINTER] = fs->top[FREELIST_POINTER];
19 /* TRD : note that abstraction_dcas loads the original value of the destination (fs->top) into the compare (fe_local)
20 (this happens of course after the CAS itself has occurred inside abstraction_dcas)
21 */
23 do
24 {
25 if( fe_local[FREELIST_POINTER] == NULL )
26 {
27 *fe = NULL;
28 return( *fe );
29 }
30 }
31 while( 0 == abstraction_dcas((volatile atom_t *) fs->top, (atom_t *) fe_local[FREELIST_POINTER]->next, (atom_t *) fe_local) );
33 *fe = (struct freelist_element *) fe_local[FREELIST_POINTER];
35 return( *fe );
36 }
42 /****************************************************************************/
43 struct freelist_element *freelist_guaranteed_pop( struct freelist_state *fs, struct freelist_element **fe )
44 {
45 assert( fs != NULL );
46 assert( fe != NULL );
48 freelist_internal_new_element( fs, fe );
50 return( *fe );
51 }
57 /****************************************************************************/
58 void freelist_push( struct freelist_state *fs, struct freelist_element *fe )
59 {
60 ALIGN(ALIGN_DOUBLE_POINTER) struct freelist_element
61 *fe_local[FREELIST_PAC_SIZE],
62 *original_fe_next[FREELIST_PAC_SIZE];
64 assert( fs != NULL );
65 assert( fe != NULL );
67 fe_local[FREELIST_POINTER] = fe;
68 fe_local[FREELIST_COUNTER] = (struct freelist_element *) abstraction_increment( (atom_t *) &fs->aba_counter );
70 original_fe_next[FREELIST_POINTER] = fs->top[FREELIST_POINTER];
71 original_fe_next[FREELIST_COUNTER] = fs->top[FREELIST_COUNTER];
73 /* TRD : note that abstraction_dcas loads the original value of the destination (fs->top) into the compare (original_fe_next)
74 (this happens of course after the CAS itself has occurred inside abstraction_dcas)
75 this then causes us in our loop, should we repeat it, to update fe_local->next to a more
76 up-to-date version of the head of the freelist
77 */
79 do
80 {
81 fe_local[FREELIST_POINTER]->next[FREELIST_POINTER] = original_fe_next[FREELIST_POINTER];
82 fe_local[FREELIST_POINTER]->next[FREELIST_COUNTER] = original_fe_next[FREELIST_COUNTER];
83 }
84 while( 0 == abstraction_dcas((volatile atom_t *) fs->top, (atom_t *) fe_local, (atom_t *) original_fe_next) );
86 return;
87 }