mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-04 22:49:32 +03:00
fix potential race on subproc field in the segment
This commit is contained in:
parent
76b0873ce2
commit
b1188ea336
5 changed files with 19 additions and 21 deletions
|
@ -397,9 +397,10 @@ typedef struct mi_segment_s {
|
||||||
bool allow_decommit;
|
bool allow_decommit;
|
||||||
bool allow_purge;
|
bool allow_purge;
|
||||||
size_t segment_size; // for huge pages this may be different from `MI_SEGMENT_SIZE`
|
size_t segment_size; // for huge pages this may be different from `MI_SEGMENT_SIZE`
|
||||||
|
mi_subproc_t* subproc; // segment belongs to sub process
|
||||||
|
|
||||||
// segment fields
|
// segment fields
|
||||||
struct mi_segment_s* next; // must be the first segment field after abandoned_next -- see `segment.c:segment_init`
|
struct mi_segment_s* next; // must be the first (non-constant) segment field -- see `segment.c:segment_init`
|
||||||
struct mi_segment_s* prev;
|
struct mi_segment_s* prev;
|
||||||
bool was_reclaimed; // true if it was reclaimed (used to limit on-free reclamation)
|
bool was_reclaimed; // true if it was reclaimed (used to limit on-free reclamation)
|
||||||
|
|
||||||
|
@ -410,7 +411,6 @@ typedef struct mi_segment_s {
|
||||||
size_t capacity; // count of available pages (`#free + used`)
|
size_t capacity; // count of available pages (`#free + used`)
|
||||||
size_t segment_info_size;// space we are using from the first page for segment meta-data and possible guard pages.
|
size_t segment_info_size;// space we are using from the first page for segment meta-data and possible guard pages.
|
||||||
uintptr_t cookie; // verify addresses in secure mode: `_mi_ptr_cookie(segment) == segment->cookie`
|
uintptr_t cookie; // verify addresses in secure mode: `_mi_ptr_cookie(segment) == segment->cookie`
|
||||||
mi_subproc_t* subproc; // segment belongs to sub process
|
|
||||||
|
|
||||||
struct mi_segment_s* abandoned_os_next; // only used for abandoned segments outside arena's, and only if `mi_option_visit_abandoned` is enabled
|
struct mi_segment_s* abandoned_os_next; // only used for abandoned segments outside arena's, and only if `mi_option_visit_abandoned` is enabled
|
||||||
struct mi_segment_s* abandoned_os_prev;
|
struct mi_segment_s* abandoned_os_prev;
|
||||||
|
|
|
@ -162,8 +162,9 @@ void _mi_arena_segment_mark_abandoned(mi_segment_t* segment)
|
||||||
mi_arena_t* arena = mi_arena_from_index(arena_idx);
|
mi_arena_t* arena = mi_arena_from_index(arena_idx);
|
||||||
mi_assert_internal(arena != NULL);
|
mi_assert_internal(arena != NULL);
|
||||||
// set abandonment atomically
|
// set abandonment atomically
|
||||||
|
mi_subproc_t* const subproc = segment->subproc; // don't access the segment after setting it abandoned
|
||||||
const bool was_unmarked = _mi_bitmap_claim(arena->blocks_abandoned, arena->field_count, 1, bitmap_idx, NULL);
|
const bool was_unmarked = _mi_bitmap_claim(arena->blocks_abandoned, arena->field_count, 1, bitmap_idx, NULL);
|
||||||
if (was_unmarked) { mi_atomic_increment_relaxed(&segment->subproc->abandoned_count); }
|
if (was_unmarked) { mi_atomic_increment_relaxed(&subproc->abandoned_count); }
|
||||||
mi_assert_internal(was_unmarked);
|
mi_assert_internal(was_unmarked);
|
||||||
mi_assert_internal(_mi_bitmap_is_claimed(arena->blocks_inuse, arena->field_count, 1, bitmap_idx));
|
mi_assert_internal(_mi_bitmap_is_claimed(arena->blocks_inuse, arena->field_count, 1, bitmap_idx));
|
||||||
}
|
}
|
||||||
|
|
|
@ -563,6 +563,7 @@ static mi_segment_t* mi_segment_os_alloc(bool eager_delayed, size_t page_alignme
|
||||||
segment->allow_decommit = !memid.is_pinned;
|
segment->allow_decommit = !memid.is_pinned;
|
||||||
segment->allow_purge = segment->allow_decommit && (mi_option_get(mi_option_purge_delay) >= 0);
|
segment->allow_purge = segment->allow_decommit && (mi_option_get(mi_option_purge_delay) >= 0);
|
||||||
segment->segment_size = segment_size;
|
segment->segment_size = segment_size;
|
||||||
|
segment->subproc = tld->subproc;
|
||||||
mi_segments_track_size((long)(segment_size), tld);
|
mi_segments_track_size((long)(segment_size), tld);
|
||||||
_mi_segment_map_allocated_at(segment);
|
_mi_segment_map_allocated_at(segment);
|
||||||
return segment;
|
return segment;
|
||||||
|
@ -628,7 +629,6 @@ static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind,
|
||||||
segment->segment_info_size = pre_size;
|
segment->segment_info_size = pre_size;
|
||||||
segment->thread_id = _mi_thread_id();
|
segment->thread_id = _mi_thread_id();
|
||||||
segment->cookie = _mi_ptr_cookie(segment);
|
segment->cookie = _mi_ptr_cookie(segment);
|
||||||
segment->subproc = tld->subproc;
|
|
||||||
|
|
||||||
// set protection
|
// set protection
|
||||||
mi_segment_protect(segment, true, tld->os);
|
mi_segment_protect(segment, true, tld->os);
|
||||||
|
|
|
@ -25,17 +25,14 @@ terms of the MIT license.
|
||||||
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
||||||
//
|
//
|
||||||
// argument defaults
|
// argument defaults
|
||||||
|
#if !defined(MI_TSAN)
|
||||||
static int THREADS = 32; // more repeatable if THREADS <= #processors
|
static int THREADS = 32; // more repeatable if THREADS <= #processors
|
||||||
static int SCALE = 25; // scaling factor
|
#else // with thread-sanitizer reduce the defaults for azure pipeline limits
|
||||||
|
static int THREADS = 8;
|
||||||
#if defined(MI_TSAN)
|
|
||||||
static int ITER = 10; // N full iterations destructing and re-creating all threads (on tsan reduce for azure pipeline limits)
|
|
||||||
#else
|
|
||||||
static int ITER = 50; // N full iterations destructing and re-creating all threads
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// static int THREADS = 8; // more repeatable if THREADS <= #processors
|
static int SCALE = 25; // scaling factor
|
||||||
// static int SCALE = 100; // scaling factor
|
static int ITER = 50; // N full iterations destructing and re-creating all threads
|
||||||
|
|
||||||
#define STRESS // undefine for leak test
|
#define STRESS // undefine for leak test
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue