diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-06 08:53:47 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-06 08:53:47 +0000 |
commit | cb62399d90f6eeaf3c42ab44730c39c2c0317746 (patch) | |
tree | e6cb59a4812ea42b43fb53c5e618411e4a34c692 | |
parent | b9cafaf5246fb240f52ebfce67ae2b72dd4eb363 (diff) | |
download | ruby-cb62399d90f6eeaf3c42ab44730c39c2c0317746.tar.gz |
* gc.c (atomic_sub_nounderflow): added to simplify atomic sub with
care about underflow.
* gc.c (objspace_malloc_increase): use it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44036 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | gc.c | 48 |
2 files changed, 29 insertions, 26 deletions
@@ -1,3 +1,10 @@ +Fri Dec 6 17:49:46 2013 Koichi Sasada <ko1@atdot.net> + + * gc.c (atomic_sub_nounderflow): added to simplify atomic sub with + care about underflow. + + * gc.c (objspace_malloc_increase): use it. + Fri Dec 6 17:10:44 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> * vm_insnhelper.c (rb_get_kwargs): get keyword argument values from an @@ -5808,6 +5808,18 @@ enum memop_type { MEMOP_TYPE_REALLOC = 3 }; +static inline void +atomic_sub_nounderflow(size_t *var, size_t sub) +{ + if (sub == 0) return; + + while (1) { + size_t val = *var; + if (val < sub) sub = 0; + if (ATOMIC_SIZE_CAS(*var, val, val-sub) == val) break; + } +} + static void objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, size_t old_size, enum memop_type type) { @@ -5815,15 +5827,7 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si ATOMIC_SIZE_ADD(malloc_increase, new_size - old_size); } else { - size_t sub = old_size - new_size; - if (sub != 0) { - retry_sub:; - { - size_t old_increase = malloc_increase; - size_t new_increase = old_increase > sub ? old_increase - sub : 0; - if (ATOMIC_SIZE_CAS(malloc_increase, old_increase, new_increase) != old_increase) goto retry_sub; - } - } + atomic_sub_nounderflow(&malloc_increase, old_size - new_size); } if (type == MEMOP_TYPE_MALLOC) { @@ -5848,21 +5852,14 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si } else { size_t dec_size = old_size - new_size; - while (1) { - size_t allocated_size = objspace->malloc_params.allocated_size; - size_t next_allocated_size; + size_t allocated_size = objspace->malloc_params.allocated_size; - if (allocated_size > dec_size) { - next_allocated_size = allocated_size - dec_size; - } - else { #if MALLOC_ALLOCATED_SIZE_CHECK - rb_bug("objspace_malloc_increase: underflow malloc_params.allocated_size."); -#endif - next_allocated_size = 0; - } - if (ATOMIC_SIZE_CAS(objspace->malloc_params.allocated_size, allocated_size, next_allocated_size) == allocated_size) break; + if (allocated_size < dec_size) { + rb_bug("objspace_malloc_increase: underflow malloc_params.allocated_size."); } +#endif + atomic_sub_nounderflow(objspace->malloc_params.allocated_size, dec_size); } if (0) fprintf(stderr, "incraese - ptr: %p, type: %s, new_size: %d, old_size: %d\n", @@ -5877,17 +5874,16 @@ objspace_malloc_increase(rb_objspace_t *objspace, void *mem, size_t new_size, si ATOMIC_SIZE_INC(objspace->malloc_params.allocations); break; case MEMOP_TYPE_FREE: - while (1) { + { size_t allocations = objspace->malloc_params.allocations; if (allocations > 0) { - if (ATOMIC_SIZE_CAS(objspace->malloc_params.allocations, allocations, allocations - 1) == allocations) break; + atomic_sub_nounderflow(objspace->malloc_params.allocations, 1); } - else { #if MALLOC_ALLOCATED_SIZE_CHECK + else { assert(objspace->malloc_params.allocations > 0); -#endif - break; } +#endif } break; case MEMOP_TYPE_REALLOC: /* ignore */ break; |