* 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
This commit is contained in:
ko1 2013-12-06 08:53:47 +00:00
parent b9cafaf524
commit cb62399d90
2 changed files with 29 additions and 26 deletions

View File

@ -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

48
gc.c
View File

@ -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;