You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by xl...@apache.org on 2007/04/20 16:45:59 UTC
svn commit: r530829 - in /harmony/enhanced/drlvm/trunk/vm/gc_gen/src:
common/ gen/ mark_compact/ mark_sweep/ thread/ trace_forward/ utils/
Author: xli
Date: Fri Apr 20 07:45:58 2007
New Revision: 530829
URL: http://svn.apache.org/viewvc?view=rev&rev=530829
Log:
HARMONY-3700 : [DRLVM][GC] fix a LOS (large object space) adaptation bug
Modified:
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Fri Apr 20 07:45:58 2007
@@ -246,6 +246,11 @@
return;
}
+void gc_assign_free_area_to_mutators(GC* gc)
+{
+ gc_gen_assign_free_area_to_mutators((GC_Gen*)gc);
+}
+
void gc_copy_interior_pointer_table_to_rootset();
void gc_reclaim_heap(GC* gc, unsigned int gc_cause)
@@ -314,6 +319,8 @@
//For_LOS_extend!
gc_space_tuner_reset(gc);
+
+ gc_assign_free_area_to_mutators(gc);
vm_resume_threads_after();
return;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp Fri Apr 20 07:45:58 2007
@@ -94,7 +94,7 @@
if((tuner->need_tune) && (!tuner->force_tune)) goto check_size;
/*tuner->force_tune must be true here!*/
los_fail_sz_uped = lspace_get_failure_size((Lspace*)lspace);
- assert(!(los_fail_sz_uped % GC_BLOCK_SIZE_BYTES));
+ assert(!(los_fail_sz_uped % KB));
if(tuner->kind == TRANS_FROM_LOS_TO_MOS){
tuner->kind = TRANS_FROM_MOS_TO_LOS;
@@ -269,7 +269,7 @@
return TRUE;
}
/*force tune here!*/
- POINTER_SIZE_INT min_tuning_uped = los->failure_size;
+ POINTER_SIZE_INT min_tuning_uped = round_up_to_size(los->failure_size, GC_BLOCK_SIZE_BYTES);
if(min_tuning_uped > max_free_for_tuning){
tuner->tuning_size = 0;
tuner->kind = TRANS_NOTHING;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp Fri Apr 20 07:45:58 2007
@@ -245,15 +245,19 @@
return;
}
-void* mos_alloc(unsigned size, Allocator *allocator){return mspace_alloc(size, allocator);}
-void* nos_alloc(unsigned size, Allocator *allocator){return fspace_alloc(size, allocator);}
-void* los_alloc(unsigned size, Allocator *allocator){return lspace_alloc(size, allocator);}
Space* gc_get_nos(GC_Gen* gc){ return (Space*)gc->nos;}
Space* gc_get_mos(GC_Gen* gc){ return (Space*)gc->mos;}
Space* gc_get_los(GC_Gen* gc){ return (Space*)gc->los;}
void gc_set_nos(GC_Gen* gc, Space* nos){ gc->nos = (Fspace*)nos;}
void gc_set_mos(GC_Gen* gc, Space* mos){ gc->mos = (Mspace*)mos;}
void gc_set_los(GC_Gen* gc, Space* los){ gc->los = (Lspace*)los;}
+
+void* mos_alloc(unsigned size, Allocator *allocator){return mspace_alloc(size, allocator);}
+void* nos_alloc(unsigned size, Allocator *allocator){return fspace_alloc(size, allocator);}
+void* los_alloc(unsigned size, Allocator *allocator){return lspace_alloc(size, allocator);}
+void* los_try_alloc(POINTER_SIZE_INT size, GC* gc){ return lspace_try_alloc((Lspace*)((GC_Gen*)gc)->los, size); }
+
+
unsigned int gc_get_processor_num(GC_Gen* gc){ return gc->_num_processors;}
@@ -320,6 +324,25 @@
return;
+}
+
+void gc_gen_assign_free_area_to_mutators(GC_Gen* gc)
+{
+ if(gc->cause == GC_CAUSE_LOS_IS_FULL){
+ Lspace* los = gc->los;
+ los->success_ptr = los_try_alloc(los->failure_size, (GC*)gc);
+ los->failure_size = 0;
+
+ }else{
+ Blocked_Space* nos = (Blocked_Space*)gc->nos;
+ if(nos->num_managed_blocks == 0) return;
+
+ Mutator *mutator = (Mutator *)gc_get_tls();
+ allocator_init_free_block((Allocator*)mutator, (Block_Header*)nos->blocks);
+ nos->free_block_idx++;
+ }
+
+ return;
}
Boolean IS_FALLBACK_COMPACTION = FALSE; /* only for debugging, don't use it. */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h Fri Apr 20 07:45:58 2007
@@ -150,12 +150,15 @@
void* mos_alloc(unsigned size, Allocator *allocator);
void* nos_alloc(unsigned size, Allocator *allocator);
void* los_alloc(unsigned size, Allocator *allocator);
+void* los_try_alloc(POINTER_SIZE_INT size, GC* gc);
+
Space* gc_get_nos(GC_Gen* gc);
Space* gc_get_mos(GC_Gen* gc);
Space* gc_get_los(GC_Gen* gc);
void gc_set_nos(GC_Gen* gc, Space* nos);
void gc_set_mos(GC_Gen* gc, Space* mos);
void gc_set_los(GC_Gen* gc, Space* los);
+
unsigned int gc_get_processor_num(GC_Gen* gc);
void gc_decide_collection_algorithm(GC_Gen* gc, char* minor_algo, char* major_algo);
@@ -165,6 +168,8 @@
void gc_gen_reclaim_heap(GC_Gen* gc);
+void gc_gen_assign_free_area_to_mutators(GC_Gen* gc);
+
void gc_gen_mode_adapt_init(GC_Gen *gc);
void gc_gen_iterate_heap(GC_Gen *gc);
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp Fri Apr 20 07:45:58 2007
@@ -272,10 +272,6 @@
}
gc_gen_mode_adapt(gc,pause_time);
- /* a heuristic: when no free block at all after this collection, we can't
- do any allocation at all. The first allocation will trigger a major collection */
- if( fspace->num_managed_blocks == 0 )
- gc->force_major_collect = TRUE;
return;
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp Fri Apr 20 07:45:58 2007
@@ -36,31 +36,9 @@
}
/* ok, got one */
Block_Header* alloc_block = (Block_Header*)&(mspace->blocks[allocated_idx - mspace->first_block_idx]);
- assert(alloc_block->status == BLOCK_FREE);
- alloc_block->status = BLOCK_IN_USE;
- /*For_statistic mos allocation infomation*/
mspace->alloced_size += GC_BLOCK_SIZE_BYTES;
-
- /* set allocation context */
- void* new_free = alloc_block->free;
- allocator->free = new_free;
-#ifndef ALLOC_ZEROING
-
- allocator->ceiling = alloc_block->ceiling;
- memset(new_free, 0, GC_BLOCK_BODY_SIZE_BYTES);
-
-#else
-
- /* the first-time zeroing area includes block header, to make subsequent allocs page aligned */
- unsigned int zeroing_size = ZEROING_SIZE - GC_BLOCK_HEADER_SIZE_BYTES;
- allocator->ceiling = (void*)((POINTER_SIZE_INT)new_free + zeroing_size);
- memset(new_free, 0, zeroing_size);
-
-#endif /* #ifndef ALLOC_ZEROING */
-
- allocator->end = alloc_block->ceiling;
- allocator->alloc_block = (Block*)alloc_block;
+ allocator_init_free_block(allocator, alloc_block);
return TRUE;
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp Fri Apr 20 07:45:58 2007
@@ -141,8 +141,10 @@
if(block->status != BLOCK_DEST)
return block;
- while(block->status == BLOCK_DEST)
+ while(block->status == BLOCK_DEST) {
block = block->next;
+ if(!block) break;
+ }
next_block_for_dest = block;
return block;
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h Fri Apr 20 07:45:58 2007
@@ -52,8 +52,13 @@
/* END of Space --> */
Free_Area_Pool* free_pool;
- /*Size of allocation which caused lspace alloc failure.*/
+ /*Size of allocation which caused lspace alloc failure.
+ *This one is used to assign area to failed collection inside gc.
+ *Resetted in every gc_assign_free_area_to_mutators
+ */
POINTER_SIZE_INT failure_size;
+ void* success_ptr;
+
void* scompact_fa_start;
void* scompact_fa_end;
}Lspace;
@@ -61,6 +66,7 @@
void lspace_initialize(GC* gc, void* reserved_base, POINTER_SIZE_INT lspace_size);
void lspace_destruct(Lspace* lspace);
Managed_Object_Handle lspace_alloc(POINTER_SIZE_INT size, Allocator* allocator);
+void* lspace_try_alloc(Lspace* lspace, POINTER_SIZE_INT alloc_size);
void lspace_sliding_compact(Collector* collector, Lspace* lspace);
void lspace_compute_object_target(Collector* collector, Lspace* lspace);
void lspace_sweep(Lspace* lspace);
@@ -78,6 +84,7 @@
while(!reach_heap_end){
//FIXME: This while shoudl be if, try it!
while(!*((POINTER_SIZE_INT*)next_area_start)){
+ assert(((Free_Area*)next_area_start)->size);
next_area_start += ((Free_Area*)next_area_start)->size;
}
if(next_area_start < (POINTER_SIZE_INT)lspace->heap_end){
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp Fri Apr 20 07:45:58 2007
@@ -148,59 +148,82 @@
return NULL;
}
+void* lspace_try_alloc(Lspace* lspace, POINTER_SIZE_INT alloc_size){
+ void* p_result = NULL;
+ Free_Area_Pool* pool = lspace->free_pool;
+ unsigned int list_hint = pool_list_index_with_size(alloc_size);
+ list_hint = pool_list_get_next_flag(pool, list_hint);
+
+ while((!p_result) && (list_hint <= MAX_LIST_INDEX)){
+ /*List hint is not the last list, so look for it in former lists.*/
+ if(list_hint < MAX_LIST_INDEX){
+ p_result = free_pool_former_lists_atomic_take_area_piece(pool, list_hint, alloc_size);
+ if(p_result){
+ memset(p_result, 0, alloc_size);
+ POINTER_SIZE_INT vold = lspace->alloced_size;
+ POINTER_SIZE_INT vnew = vold + alloc_size;
+ while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){
+ vold = lspace->alloced_size;
+ vnew = vold + alloc_size;
+ }
+ return p_result;
+ }else{
+ list_hint ++;
+ list_hint = pool_list_get_next_flag(pool, list_hint);
+ continue;
+ }
+ }
+ /*List hint is the last list, so look for it in the last list.*/
+ else
+ {
+ p_result = free_pool_last_list_atomic_take_area_piece(pool, alloc_size);
+ if(p_result){
+ memset(p_result, 0, alloc_size);
+ POINTER_SIZE_INT vold = lspace->alloced_size;
+ POINTER_SIZE_INT vnew = vold + alloc_size;
+ while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){
+ vold = lspace->alloced_size;
+ vnew = vold + alloc_size;
+ }
+ return p_result;
+ }
+ else break;
+ }
+ }
+ return p_result;
+}
+
void* lspace_alloc(POINTER_SIZE_INT size, Allocator *allocator)
{
unsigned int try_count = 0;
void* p_result = NULL;
- unsigned int list_hint = 0;
POINTER_SIZE_INT alloc_size = ALIGN_UP_TO_KILO(size);
Lspace* lspace = (Lspace*)gc_get_los((GC_Gen*)allocator->gc);
Free_Area_Pool* pool = lspace->free_pool;
-
+
while( try_count < 2 ){
- list_hint = pool_list_index_with_size(alloc_size);
- list_hint = pool_list_get_next_flag(pool, list_hint);
- while((!p_result) && (list_hint <= MAX_LIST_INDEX)){
- /*List hint is not the last list, so look for it in former lists.*/
- if(list_hint < MAX_LIST_INDEX){
- p_result = free_pool_former_lists_atomic_take_area_piece(pool, list_hint, alloc_size);
- if(p_result){
- memset(p_result, 0, size);
- POINTER_SIZE_INT vold = lspace->alloced_size;
- POINTER_SIZE_INT vnew = vold + alloc_size;
- while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){
- vold = lspace->alloced_size;
- vnew = vold + alloc_size;
- }
- return p_result;
- }else{
- list_hint ++;
- list_hint = pool_list_get_next_flag(pool, list_hint);
- continue;
- }
- }
- /*List hint is the last list, so look for it in the last list.*/
- else
- {
- p_result = free_pool_last_list_atomic_take_area_piece(pool, alloc_size);
- if(p_result){
- memset(p_result, 0, size);
- POINTER_SIZE_INT vold = lspace->alloced_size;
- POINTER_SIZE_INT vnew = vold + alloc_size;
- while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){
- vold = lspace->alloced_size;
- vnew = vold + alloc_size;
- }
- return p_result;
- }
- else break;
- }
- }
+ if(p_result = lspace_try_alloc(lspace, alloc_size))
+ return p_result;
+
/*Failled, no adequate area found in all lists, so GC at first, then get another try.*/
if(try_count == 0){
vm_gc_lock_enum();
- lspace->failure_size = round_up_to_size(alloc_size, GC_BLOCK_SIZE_BYTES);
+ /*Check again if there is space for the obj, for maybe other mutator
+ threads issus a GC in the time gap of waiting the gc lock*/
+ if(p_result = lspace_try_alloc(lspace, alloc_size)){
+ vm_gc_unlock_enum();
+ return p_result;
+ }
+ lspace->failure_size = round_up_to_size(alloc_size, KB);
+
gc_reclaim_heap(allocator->gc, GC_CAUSE_LOS_IS_FULL);
+
+ if(lspace->success_ptr){
+ p_result = lspace->success_ptr;
+ lspace->success_ptr = NULL;
+ vm_gc_unlock_enum();
+ return p_result;
+ }
vm_gc_unlock_enum();
try_count ++;
}else{
@@ -327,7 +350,6 @@
/*For_statistic los information.*/
lspace->alloced_size = 0;
- lspace->failure_size = 0;
lspace->surviving_size = 0;
los_boundary = lspace->heap_end;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h Fri Apr 20 07:45:58 2007
@@ -110,6 +110,34 @@
}
+inline void allocator_init_free_block(Allocator* allocator, Block_Header* alloc_block)
+{
+ assert(alloc_block->status == BLOCK_FREE);
+ alloc_block->status = BLOCK_IN_USE;
+
+ /* set allocation context */
+ void* new_free = alloc_block->free;
+ allocator->free = new_free;
+
+#ifndef ALLOC_ZEROING
+
+ allocator->ceiling = alloc_block->ceiling;
+ memset(new_free, 0, GC_BLOCK_BODY_SIZE_BYTES);
+
+#else
+ /* the first-time zeroing area includes block header, to make subsequent allocs page aligned */
+ unsigned int zeroing_size = ZEROING_SIZE - GC_BLOCK_HEADER_SIZE_BYTES;
+ allocator->ceiling = (void*)((POINTER_SIZE_INT)new_free + zeroing_size);
+ memset(new_free, 0, zeroing_size);
+
+#endif /* #ifndef ALLOC_ZEROING */
+
+ allocator->end = alloc_block->ceiling;
+ allocator->alloc_block = (Block*)alloc_block;
+
+ return;
+}
+
inline void alloc_context_reset(Allocator* allocator)
{
Block_Header* block = (Block_Header*)allocator->alloc_block;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp Fri Apr 20 07:45:58 2007
@@ -21,7 +21,7 @@
#include "fspace.h"
static Boolean fspace_alloc_block(Fspace* fspace, Allocator* allocator)
-{
+{
alloc_context_reset(allocator);
/* now try to get a new block */
@@ -36,29 +36,9 @@
}
/* ok, got one */
Block_Header* alloc_block = (Block_Header*)&(fspace->blocks[allocated_idx - fspace->first_block_idx]);
- assert(alloc_block->status == BLOCK_FREE);
- alloc_block->status = BLOCK_IN_USE;
- /* set allocation context */
- void* new_free = alloc_block->free;
- allocator->free = new_free;
-
-#ifndef ALLOC_ZEROING
-
- allocator->ceiling = alloc_block->ceiling;
- memset(new_free, 0, GC_BLOCK_BODY_SIZE_BYTES);
-
-#else
- /* the first-time zeroing area includes block header, to make subsequent allocs page aligned */
- unsigned int zeroing_size = ZEROING_SIZE - GC_BLOCK_HEADER_SIZE_BYTES;
- allocator->ceiling = (void*)((POINTER_SIZE_INT)new_free + zeroing_size);
- memset(new_free, 0, zeroing_size);
-
-#endif /* #ifndef ALLOC_ZEROING */
-
- allocator->end = alloc_block->ceiling;
- allocator->alloc_block = (Block*)alloc_block;
-
+ allocator_init_free_block(allocator, alloc_block);
+
return TRUE;
}
@@ -84,12 +64,18 @@
if ( !space_has_free_block((Blocked_Space*)fspace) ) {
if(attempts < 2) {
gc_reclaim_heap(allocator->gc, GC_CAUSE_NOS_IS_FULL);
+ if(allocator->alloc_block){
+ vm_gc_unlock_enum();
+ break;
+ }
+
attempts++;
+
}else{
vm_gc_unlock_enum();
return NULL;
}
- }
+ }
vm_gc_unlock_enum();
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h Fri Apr 20 07:45:58 2007
@@ -95,9 +95,12 @@
POINTER_SIZE_INT old_value = *p_word;
POINTER_SIZE_INT mask = (POINTER_SIZE_INT)1 << bit_offset;
POINTER_SIZE_INT new_value = old_value|mask;
-
- *p_word = new_value;
-
+ while (true) {
+ POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value);
+ if (temp == old_value) break;
+ old_value = *p_word;
+ new_value = old_value|mask;
+ }
return;
}
@@ -114,9 +117,12 @@
POINTER_SIZE_INT old_value = *p_word;
POINTER_SIZE_INT mask = ~((POINTER_SIZE_INT)1 << bit_offset);
POINTER_SIZE_INT new_value = old_value & mask;
-
- *p_word = new_value;
-
+ while (true) {
+ POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value);
+ if (temp == old_value) break;
+ old_value = *p_word;
+ new_value = old_value & mask;
+ }
return;
}
#endif