Ivan Maidanski [Fri, 17 Nov 2017 18:20:54 +0000 (21:20 +0300)]
Revert 'Workaround a hang in sigsuspend if compiled with Thread Sanitizer'
This reverts commit
04fd7b5309596423e4342502d3123028d836d551.
Because it does not avoid hangs in all cases when stopping the world.
A better solution is to re-enable signals in the suspend handler.
Ivan Maidanski [Fri, 17 Nov 2017 17:36:47 +0000 (20:36 +0300)]
Allow to turn on spin locking even if thread-local allocations are used
* include/private/gc_locks.h [GC_PTHREADS && !GC_WIN32_THREADS
&& THREAD_LOCAL_ALLOC && !USE_PTHREAD_LOCKS] (UNCOND_LOCK,
UNCOND_UNLOCK): Use spin locks if USE_SPIN_LOCK is defined by client.
Ivan Maidanski [Fri, 17 Nov 2017 16:41:30 +0000 (19:41 +0300)]
Eliminate TSan false positive for stop_info.stack_ptr
Without this patch, Thread Sanitizer reports a data race between
GC_has_other_debug_info() and the code which sets stop_info.stack_ptr.
* include/private/pthread_support.h (GC_Thread_Rep.status): Move the
field to be before stop_info one (so, the latter now has the offset
of at least 3 in words, while oh.oh_sz has the offset of 2 in words
(when KEEP_BACK_PTRS, MAKE_BACK_GRAPH and NEED_CALLINFO are not
defined)).
Ivan Maidanski [Fri, 17 Nov 2017 08:07:03 +0000 (11:07 +0300)]
Eliminate TSan warning about data race when accessing GC_debugging_started
Now GC_debugging_started variable is double-checked with the allocation
lock held before calling GC_start_debugging_inner.
* dbg_mlc.c (GC_start_debugging_inner): Define as GC_INNER (instead of
STATIC).
* dbg_mlc.c [THREADS] (GC_start_debugging): Define as STATIC; do not
call GC_start_debugging_inner() if GC_debugging_started.
* dbg_mlc.c [!THREADS] (GC_start_debugging): Define as macro (redirect
to GC_start_debugging_inner).
* gcj_mlc.c (GC_debug_gcj_malloc): Call GC_start_debugging_inner
(holding the lock) instead of GC_start_debugging.
* include/private/gc_priv.h (GC_start_debugging): Rename to
GC_start_debugging_inner; improve usage comment.
Ivan Maidanski [Thu, 16 Nov 2017 08:20:32 +0000 (11:20 +0300)]
Fix typo in a function name in README.sgi
* doc/README.sgi (4): Fix a typo ("pthread_cond_timedwait").
Ivan Maidanski [Wed, 15 Nov 2017 22:15:14 +0000 (01:15 +0300)]
Workaround TSan false positives in extend_size_map
Thread Sanitizer reports data races between fill_size_map (called from
GC_extend_size_map) and GC_gcj_malloc[_ignore_off_page],
GC_malloc_kind_global, GC_generic_malloc_uncollectable,
GC_malloc_explicitly_typed_ignore_off_page which read a value from
GC_size_map before acquiring the allocation lock. These races could
be ignored as the value is verified after acquiring the lock.
* alloc.c: Refine comment about GC_allocobj (and GC_size_map) usage
for the case of a multi-threaded environment.
* malloc.c (fill_size_map): New static function (with
GC_ATTR_NO_SANITIZE_THREAD attribute).
* malloc.c (GC_extend_size_map): Use fill_size_map() to fill in
a region of GC_size_map.
Ivan Maidanski [Mon, 13 Nov 2017 19:58:37 +0000 (22:58 +0300)]
Remove GENERAL_MALLOC internal macro
(code refactoring)
* alloc.c: Update comment (about GC_allocobj usage).
* include/private/gc_priv.h (GENERAL_MALLOC): Remove.
* include/private/gc_priv.h (GENERAL_MALLOC_IOP): Move to typd_mlc.c.
* malloc.c (GC_malloc_kind_global): Expand GENERAL_MALLOC macro; copy
the comment from gc_priv.h.
Ivan Maidanski [Mon, 13 Nov 2017 06:04:04 +0000 (09:04 +0300)]
Workaround a hang in sigsuspend if compiled with Thread Sanitizer
Issue #181 (bdwgc).
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL
&& THREAD_SANITIZER] (GC_suspend_handler_inner): Use sched_yield()
instead of sigsuspend(&suspend_handler_mask); add TODO item.
Ivan Maidanski [Mon, 13 Nov 2017 04:58:36 +0000 (07:58 +0300)]
Workaround TSan false positives in suspend/resume_thread
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL
&& GC_ENABLE_SUSPEND_THREAD] (set_suspended_ext_flag): New static
function (with GC_ATTR_NO_SANITIZE_THREAD attribute); add comment.
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL
&& GC_ENABLE_SUSPEND_THREAD] (GC_suspend_thread): Call
set_suspended_ext_flag() instead of t->flags|=SUSPENDED_EXT.
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL
&& GC_ENABLE_SUSPEND_THREAD] (GC_resume_thread): Add
GC_ATTR_NO_SANITIZE_THREAD attribute; add comment.
Ivan Maidanski [Fri, 10 Nov 2017 17:07:16 +0000 (20:07 +0300)]
Fix data race when getting object size in explicitly-typed allocators
* typd_mlc.c (COMPLEX): Reformat comment.
* typd_mlc.c (GC_malloc_explicitly_typed,
GC_malloc_explicitly_typed_ignore_off_page, GC_calloc_explicitly_typed):
Always use BYTES_TO_GRANULES(GC_size(op)) instead of GC_size_map[lb] to
determine size of the allocated object in granules (because the value
of GC_size_map[lb] might be updated by another thread since the value
use in GC_malloc_kind); add comment.
Ivan Maidanski [Fri, 10 Nov 2017 15:44:57 +0000 (18:44 +0300)]
Remove 'ifdef USE_SPIN_LOCK' which is always false in gc_locks.h
(fix commit 9a20535)
* include/private/gc_locks.h [!GC_WIN32_THREADS && GC_PTHREADS
&& USE_PTHREAD_LOCKS && !GC_ASSERTIONS && NO_PTHREAD_TRYLOCK
&& USE_SPIN_LOCK] (UNCOND_LOCK): Define to
pthread_mutex_lock(&GC_allocate_ml) instead of GC_lock().
Ivan Maidanski [Fri, 10 Nov 2017 15:14:55 +0000 (18:14 +0300)]
Workaround TSan false positive in write fault handler
The data races reported between GC_write_fault_handler,
catch_exception_raise and GC_install_header, GC_remove_header are OK
as the added or removed header should be already unprotected.
* os_dep.c [MPROTECT_VDB && THREADS] (is_header_found_async): New
static function (with GC_ATTR_NO_SANITIZE_THREAD attribute).
* os_dep.c [MPROTECT_VDB && !THREADS] (is_header_found_async): New
macro.
* os_dep.c [MPROTECT_VDB && !DARWIN] (GC_write_fault_handler): Use
is_header_found_async() instead of HDR(addr)!=0.
* os_dep.c [MPROTECT_VDB && DARWIN] (catch_exception_raise): Likewise.
Ivan Maidanski [Fri, 10 Nov 2017 07:33:32 +0000 (10:33 +0300)]
Fix typo in 'gcdescr' documentation file
* doc/gcdescr.md (Allocation): Fix a typo ("the request is rounded").
Paul Bone [Fri, 10 Nov 2017 07:12:57 +0000 (10:12 +0300)]
Add basic calculation of the total full-collection time
Issue #139 (bdwgc).
New API functions: GC_start_performance_measurement,
GC_get_full_gc_total_time.
This patch is based on code originally written by Zoltan Somogyi
on 2008-03-18.
* alloc.c [!NO_CLOCK] (full_gc_total_time, measure_performance): New
static variable definition; add comment.
* alloc.c [!NO_CLOCK] (GC_start_performance_measurement,
GC_get_full_gc_total_time): New API function definition.
* alloc.c [!NO_CLOCK] (GC_try_to_collect_inner): Declare
start_time_valid local variable; set start_time_valid to true if
GET_TIME(start_time) is called; call GET_TIME(start_time) also if
measure_performance; declare time_diff local variable (used to store
the result of MS_TIME_DIFF()); GET_TIME(current_time) is called only
if start_time_valid; update full_gc_total_time if measure_performance.
* include/gc.h (GC_start_performance_measurement,
GC_get_full_gc_total_time): New API function declaration.
* tests/test.c (INIT_PERF_MEASUREMENT): New macro.
* tests/test.c (GC_COND_INIT): Call INIT_PERF_MEASUREMENT.
* tests/test.c [!NO_CLOCK] (check_heap_stats): Call
GC_get_full_gc_total_time() and print the total time of full
collections.
Ivan Maidanski [Fri, 3 Nov 2017 18:30:23 +0000 (21:30 +0300)]
Fix double lock in a_set(f(a_get())) expression in gctest
(fix commit 8f5746e)
* tests/test.c [!AO_HAVE_store_release] (AO_store_release): Replace
macro with a static function definition (so, new_val argument is
evaluated before acquiring the lock).
Ivan Maidanski [Fri, 3 Nov 2017 17:08:09 +0000 (20:08 +0300)]
Fix data race in a list referenced by A.aa (gctest)
* tests/test.c [!AO_HAVE_load] (AO_load): Remove macro.
* tests/test.c [!AO_HAVE_store] (AO_store): Likewise.
* tests/test.c [!AO_HAVE_load_acquire] (AO_load_acquire): New static
function (which uses FINALIZER_LOCK/FINALIZER_UNLOCK).
* tests/test.c [!AO_HAVE_store_release] (AO_store_release): New macro
(which uses FINALIZER_LOCK/FINALIZER_UNLOCK).
* tests/test.c [!AO_HAVE_fetch_and_add1] (AO_fetch_and_add1): Add
comment.
* tests/test.c (a_set): Use AO_store_release() instead of AO_store().
* tests/test.c (a_get): Use AO_load_acquire() instead of AO_load().
* tests/test.c (reverse_test_inner): Improve comment about thread
safety of a_set(reverse(reverse(a_get()))).
Ivan Maidanski [Fri, 3 Nov 2017 08:03:04 +0000 (11:03 +0300)]
Avoid data race in finalized_count (gctest)
* tests/test.c (FINALIZER_LOCK, FINALIZER_UNLOCK): New macro.
* tests/test.c [GC_PTHREADS] (incr_lock): Move static variable out
of finalizer() and mktree() (use a single lock variable to access
finalized_count in finalizer, mktree and tree_test).
* tests/test.c (dropped_something): Change type back to int; remove
volatile.
* tests/test.c (finalizer, mktree): Use FINALIZER_[UN]LOCK() instead
of PCR_ThCrSec_Enter/ExitSys(), pthread_mutex_[un]lock(),
Enter/LeaveCriticalSection().
* tests/test.c (tree_test): Use FINALIZER_[UN]LOCK() to avoid data
race when accessing finalized_count and dropped_something; do not use
AO_load() and AO_store() to access dropped_something.
* tests/test.c
Ivan Maidanski [Thu, 2 Nov 2017 21:58:18 +0000 (00:58 +0300)]
Eliminate TSan warning about A.dummy in gctest
* tests/test.c (reverse_test_inner): Move A.dummy=17 to
set_print_procs().
* tests/test.c (set_print_procs): Add comment.
Ivan Maidanski [Thu, 2 Nov 2017 21:38:00 +0000 (00:38 +0300)]
Revert 'Eliminate TSan warnings (false positives) in gctest'
This reverts commit
c7837f864970e3859a3b35b9b8c0858a3548a457.
Because it does not avoid potential data race between GC_malloc
(invoked from cons) and check_ints; the proper solution seems to
just use AO_load_acquire and AO_store_release to access A.aa.
Ivan Maidanski [Wed, 1 Nov 2017 21:31:11 +0000 (00:31 +0300)]
Eliminate TSan warnings (false positives) in gctest
* tests/test.c (struct SEXPR): Declare first.
* tests/test.c (union sexpr_or_aot_u): New type.
* tests/test.c (struct SEXPR): Replace struct SEXPR* to sexpr_or_aot_u.
* tests/test.c (car, cdr, small_cons_uncollectable): Add .p suffix when
accessing sexpr_car and sexpr_cdr fields.
* tests/test.c [GC_GCJ_SUPPORT] (fake_gcj_mark_proc, gcj_cons):
Likewise.
* tests/test.c [!VERY_SMALL_CONFIG] (small_cons): Likewise.
* tests/test.c (atomic_car, atomic_cdr): New macro; add comment.
* tests/test.c [!VERY_SMALL_CONFIG] (cons): Store atomic_car and
atomic_cdr atomically.
* tests/test.c [VERY_SMALL_CONFIG] (small_cons): Likewise.
* tests/test.c [!VERY_SMALL_CONFIG] (cons): Ignore store random value
at *p if p points inside r->sexpr_car/cdr; add comment.
* tests/test.c (reverse1, check_ints): Use atomic_car() and
atomic_cdr() instead of car() and cdr(), respectively.
* tests/test.c (reverse_test_inner): Move A.dummy=17 to
set_print_procs().
* tests/test.c (set_print_procs): Add comment.
Ivan Maidanski [Tue, 31 Oct 2017 21:38:00 +0000 (00:38 +0300)]
Workaround TSan false positives in mark_from, push_*_eager
* mark.c (GC_mark_from, GC_push_all_eager): Annotate with
GC_ATTR_NO_SANITIZE_THREAD.
* mark.c [WRAP_MARK_SOME && PARALLEL_MARK] (GC_push_conditional_eager):
Likewise.
Ivan Maidanski [Tue, 31 Oct 2017 08:49:55 +0000 (11:49 +0300)]
Workaround TSan false positive in [set_]mark_bit_from_hdr
There is no data race between GC_set_fl_marks and GC_is_marked because
bit_no is different.
* include/private/gc_priv.h [THREADS && THREAD_SANITIZER]: Include
gc_atomic_ops.h.
* include/private/gc_priv.h [!USE_MARK_BYTES && THREAD_SANITIZER
&& THREADS] (OR_WORD): Use AO_or; update comment.
Ivan Maidanski [Mon, 30 Oct 2017 22:09:56 +0000 (01:09 +0300)]
Workaround TSan false positive in invoke_finalizers
* finalize.c [THREADS && !THREAD_SANITIZER] (GC_invoke_finalizers): Do
not compare bytes_freed_before to GC_bytes_freed without the lock; add
comment.
* include/private/gc_priv.h (_GC_arrays._finalizer_bytes_freed): Replace
"mem." to "memory" in a comment.
Paul Bone [Sun, 29 Oct 2017 07:39:31 +0000 (10:39 +0300)]
Print time passed since GC initialization in GC_dump
Issue #139 (bdwgc).
* misc.c [!NO_DEBUGGING && !NO_CLOCK] (GC_init_time): New static
variable.
* misc.c [!NO_DEBUGGING && !NO_CLOCK] (GC_init): Set GC_init_time.
* misc.c [!NO_DEBUGGING && !NO_CLOCK] (GC_dump_named): Define
current_time local variable; print the time since GC initialization
(in milliseconds); add comment.
Ivan Maidanski [Thu, 26 Oct 2017 05:35:37 +0000 (08:35 +0300)]
Update ChangeLog file
Ivan Maidanski [Thu, 26 Oct 2017 05:31:47 +0000 (08:31 +0300)]
Update ChangeLog file (v7.6 changes only)
Ivan Maidanski [Wed, 25 Oct 2017 15:32:35 +0000 (18:32 +0300)]
Update ChangeLog file (v7.4 changes only)
Ivan Maidanski [Wed, 25 Oct 2017 08:45:38 +0000 (11:45 +0300)]
Do not use system clock consistently if NO_CLOCK
Issue #139 (bdwgc).
* alloc.c (GC_try_to_collect_inner, world_stopped_total_time,
world_stopped_total_divisor, MAX_TOTAL_TIME_DIVISOR, GC_stopped_mark):
Replace "ifndef SMALL_CONFIG" with "ifndef NO_CLOCK".
* reclaim.c (GC_reclaim_all): Likewise.
* alloc.c (GC_finish_collection): Replace "ifndef SMALL_CONFIG" with
"ifndef NO_CLOCK" except for GC_print_finalization_stats invocation.
* doc/README.macros (NO_CLOCK): Document.
* include/private/gc_priv.h (CLOCK_TYPE, GET_TIME, MS_TIME_DIFF): Do
not define if NO_CLOCK.
* include/private/gc_priv.h (GC_print_stats): Define as a macro (to 0)
only if both NO_CLOCK and SMALL_CONFIG are defined.
* misc.c (GC_print_stats): Do not define if both NO_CLOCK and
SMALL_CONFIG are defined.
* misc.c (GC_init): Do not set GC_print_stats only if both NO_CLOCK
and SMALL_CONFIG are defined.
* tests/test.c (run_one_test): Do not define start_time, reverse_time,
time_diff local variables (and do not use GET_TIME, MS_TIME_DIFF) if
NO_CLOCK is defined.
Ivan Maidanski [Wed, 25 Oct 2017 08:12:34 +0000 (11:12 +0300)]
Travis CI: Test NO_CLOCK
Ivan Maidanski [Tue, 24 Oct 2017 21:06:22 +0000 (00:06 +0300)]
Make extend_size_map() static
(code refactoring)
* include/private/gc_priv.h (GC_extend_size_map): Remove prototype.
* malloc.c (GC_extend_size_map): Move the function definition from
misc.c; change GC_INNER to STATIC; reformat code; remove j and
much_smaller_than_i local variables; add assertions that I_HOLD_LOCK
and GC_size_map[i]==0; remove comment that GC_size_map[i] is expected
to be zero.
* malloc.c (GC_generic_malloc_inner): Capitalize the first letter of
the description comment.
* misc.c (GC_extend_size_map): Remove the definition.
Ivan Maidanski [Mon, 23 Oct 2017 21:10:12 +0000 (00:10 +0300)]
Fix typos in documentation (for extend_size_map and ews4800)
* doc/README.ews4800: Fix typos ("32-bit", "64-bit").
* misc.c (GC_extend_size_map): Fix typo ("16-byte") in a comment.
Ivan Maidanski [Fri, 20 Oct 2017 18:54:06 +0000 (21:54 +0300)]
Add two-argument alloc_size attribute to calloc_explicitly_typed (GCC)
* include/gc_config_macros.h [!GC_ATTR_CALLOC_SIZE]
(GC_ATTR_CALLOC_SIZE): New macro (which uses alloc_size attribute
if GCC or Clang).
* include/gc_typed.h (GC_calloc_explicitly_typed): Add
GC_ATTR_CALLOC_SIZE(1,2) attribute.
Ivan Maidanski [Fri, 20 Oct 2017 18:15:54 +0000 (21:15 +0300)]
Use __declspec(allocator) for malloc-like prototypes (MS VS 2015+)
* include/gc_config_macros.h [_MSC_VER>=1900 && !__EDG__]
(GC_ATTR_MALLOC): Add __declspec(allocator).
Ivan Maidanski [Fri, 20 Oct 2017 09:16:20 +0000 (12:16 +0300)]
Revert 'Never try to include private/config.h'
This reverts commit
6abcbd9101a17443a848e58f6bad45d0b0aa4d1a.
Because "config.h" file may be located in some folder other than the
parent of "private" folder, e.g. during "make distcheck".
Ivan Maidanski [Thu, 19 Oct 2017 21:25:52 +0000 (00:25 +0300)]
Workaround Thread Sanitizer (TSan) false positive warnings (partially)
This patch covers only data race false positive warnings reported in
async_set_pht_entry_from_index, GC_clear_stack, GC_invoke_finalizers,
GC_lock, GC_noop1, GC_notify_or_invoke_finalizers, GC_pthread_create,
GC_suspend_handler_inner, I_DONT_HOLD_LOCK.
* finalize.c (GC_should_invoke_finalizers): Add
GC_ATTR_NO_SANITIZE_THREAD.
* mark.c (GC_noop1): Likewise.
* os_dep.c [MPROTECT_VDB && THREADS && AO_HAVE_test_and_set_acquire]
(async_set_pht_entry_from_index): Likewise.
* finalize.c (GC_invoke_finalizers, GC_notify_or_invoke_finalizers):
Call GC_should_invoke_finalizers() instead of
GC_fnlz_roots.finalize_now!=NULL.
* include/private/gc_locks.h [(GC_WIN32_THREADS && !USE_PTHREAD_LOCKS
|| GC_PTHREADS) && GC_ASSERTIONS && THREAD_SANITIZER]
(I_DONT_HOLD_LOCK): Define to TRUE; add comment.
* include/private/gc_locks.h [!GC_ALWAYS_MULTITHREADED
&& THREAD_SANITIZER] (set_need_to_lock): Do not set GC_need_to_lock if
already set; add comment.
* include/private/gc_priv.h [!GC_ATTR_NO_SANITIZE_THREAD]
(GC_ATTR_NO_SANITIZE_THREAD): New macro.
* include/private/gcconfig.h [__has_feature &&
__has_feature(thread_sanitizer)] (THREAD_SANITIZER): Define.
* misc.c [THREADS] (next_random_no): New static function (with
GC_ATTR_NO_SANITIZE_THREAD).
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL]
(update_last_stop_count): Likewise.
* pthread_support.c [THREAD_SANITIZER && (USE_SPIN_LOCK
|| !NO_PTHREAD_TRYLOCK)] (is_collecting): Likewise.
* pthread_support.c [USE_SPIN_LOCK] (set_last_spins_and_high_spin_max,
reset_spin_max): Likewise.
* misc.c [THREADS] (GC_clear_stack): Remove random_no static variable;
use next_random_no() instead of ++random_no%13.
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL]
(GC_suspend_handler_inner): Call update_last_stop_count() instead of
me->stop_info.last_stop_count=my_stop_count.
* pthread_support.c [USE_SPIN_LOCK || !NO_PTHREAD_TRYLOCK] (SPIN_MAX):
Define only if not yet.
* pthread_support.c [USE_SPIN_LOCK || !NO_PTHREAD_TRYLOCK]
(GC_collecting): Initialize to FALSE instead of 0.
* pthread_support.c [!(THREAD_SANITIZER && (USE_SPIN_LOCK
|| !NO_PTHREAD_TRYLOCK))] (is_collecting): Define as a macro.
* pthread_support.c [USE_SPIN_LOCK] (low_spin_max, high_spin_max,
spin_max, last_spins): Move definition out of GC_lock().
* pthread_support.c (GC_lock): Use is_collecting(),
set_last_spins_and_high_spin_max() and reset_spin_max().
Ivan Maidanski [Wed, 18 Oct 2017 19:37:30 +0000 (22:37 +0300)]
Refine should_invoke_finalizers documentation
* include/gc.h (GC_should_invoke_finalizers): Add comment that it is
not synchronized.
Ivan Maidanski [Wed, 18 Oct 2017 10:34:08 +0000 (13:34 +0300)]
Never try to include private/config.h
config.h is now located in "include" folder (not "include/private").
* include/private/gc_pmark.h [HAVE_CONFIG_H && !GC_PRIVATE_H]
(include config.h): Add "../" prefix.
* include/private/gc_priv.h [HAVE_CONFIG_H] (include config.h):
Likewise.
Ivan Maidanski [Tue, 17 Oct 2017 21:20:47 +0000 (00:20 +0300)]
.gitignore: Do not ignore include/private/config.h
config.h was moved to "include" folder in gc-7.4.0.
Ivan Maidanski [Tue, 17 Oct 2017 08:52:20 +0000 (11:52 +0300)]
Update AUTHORS file (add Erik M. Bray)
Erik M. Bray [Tue, 17 Oct 2017 08:50:03 +0000 (11:50 +0300)]
Use mprotect instead of mmap in GC_unmap() on Cygwin
Issue #187 (BDWGC).
* configure.ac [$enable_munmap!="" && $enable_munmap!=no]
(USE_WINALLOC): Replace AC_DEFINE with AH_TEMPLATE; remove comment
about a workaround for Cygwin; remove "if $host=*-*-cygwin*".
* os_dep.c [CYGWIN32 && USE_MUNMAP] (GC_setpagesize): Set GC_page_size
to dwAllocationGranularity (instead of dwPageSize); add comment; add
assertion that dwAllocationGranularity is not less than dwPageSize.
* os_dep.c [USE_MUNMAP && CYGWIN32 && !USE_WINALLOC] (GC_unmap,
GC_unmap_gap): Call mprotect() instead of mmap(); add comment.
Ivan Maidanski [Mon, 16 Oct 2017 21:02:27 +0000 (00:02 +0300)]
Fix 'package requirements (atomic_ops) were not met' configure error
(fix commit 3d34335)
* configure.ac [$missing_libatomic_ops] (PKG_CHECK_MODULES):
Pass no-op to action-if-not-found parameter (because the default
action-if-not-found ends the execution with an error in case of the
missing dependency).
Ivan Maidanski [Mon, 16 Oct 2017 08:00:53 +0000 (11:00 +0300)]
Allow PKG_CHECK_MODULES in configure.ac to be commented out easily
(code refactoring)
* configure.ac [$with_libatomic_ops!=no && $with_libatomic_ops!=none]
(missing_libatomic_ops): Set to true (before PKG_CHECK_MODULES).
* configure.ac [$missing_libatomic_ops] (PKG_CHECK_MODULES): Set
missing_libatomic_ops back to false if atomic_ops module is not found;
add comment (about pkg-config and the possibility to comment out
PKG_CHECK_MODULES).
Ivan Maidanski [Mon, 16 Oct 2017 07:25:57 +0000 (10:25 +0300)]
New API function (GC_is_init_called) to check if BDWGC is initialized
Issue #186 (bdwgc).
* include/gc.h (GC_is_init_called): New API function declaration.
* misc.c (GC_is_init_called): New API function definition.
* tests/test.c (check_heap_stats): Add a test that GC is initialized.
Ivan Maidanski [Thu, 12 Oct 2017 22:38:25 +0000 (01:38 +0300)]
Test GC initialization from non-main thread on FreeBSD and NetBSD
Issue #180 (bdwgc).
* tests/initsecondarythread.c [(FREEBSD || LINUX || NETBSD)
&& !NO_PTHREAD_GETATTR_NP && !NO_PTHREAD_ATTR_GET_NP] (main): Do not
call GC_INIT().
Ivan Maidanski [Thu, 12 Oct 2017 22:08:40 +0000 (01:08 +0300)]
Update ChangeLog file
Ivan Maidanski [Thu, 12 Oct 2017 08:01:53 +0000 (11:01 +0300)]
Update ChangeLog file (v7.6 changes only)
Ivan Maidanski [Tue, 10 Oct 2017 22:06:54 +0000 (01:06 +0300)]
Update ChangeLog file (v7.2 - v7.4 changes only)
Ivan Maidanski [Mon, 9 Oct 2017 19:17:15 +0000 (22:17 +0300)]
Support GC_init (and get_stack_base) from non-main thread on NetBSD
Now GC_get_[main_]stack_base uses pthread_getattr_np() and
pthread_attr_getstack() to determine the stack base address on NetBSD.
* include/private/gcconfig.h [NETBSD && !NO_PTHREAD_GETATTR_NP]
(HAVE_PTHREAD_GETATTR_NP): Define.
Ivan Maidanski [Mon, 9 Oct 2017 19:07:24 +0000 (22:07 +0300)]
Eliminate TSan warnings for all counters and A.aa variable (gctest)
Now most of the counters in gctest are updated using atomic increment.
And, the values of gctest dropped_something and A.aa variables are
updated and fetch using the atomic primitives.
* tests/test.c [!AO_CLEAR] (AO_t): Define.
* tests/test.c [!AO_HAVE_load] (AO_load): Define (as a non-atomic
operation).
* tests/test.c [!AO_HAVE_store] (AO_store): Likewise.
* tests/test.c [!AO_HAVE_fetch_and_add1] (AO_fetch_and_add1): Likewise.
* tests/test.c (stubborn_count, uncollectable_count,
collectable_count, atomic_count, realloc_count): Change type from int
to AO_t; add volatile qualifier; update comment; remove FIXME.
* tests/test.c (extra_count): Define unconditionally; change type from
int to AO_t; add volatile qualifier; update comment.
* tests/test.c [!VERY_SMALL_CONFIG] (cons): Use AO_fetch_and_add1 to
get and update the values of extra_count and stubborn_count.
* tests/test.c (small_cons_uncollectable): Use AO_fetch_and_add1 to
update the value of uncollectable_count.
* tests/test.c [!DBG_HDRS_ALL] (run_one_test): Likewise.
* tests/test.c [GC_GCJ_SUPPORT] (gcj_cons): Remove obj_cnt static
variable; use extra_count instead of obj_cnt; use AO_fetch_and_add1 to
get and update the value of extra_count.
* tests/test.c (A): Add volatile qualifier; change the type of aa
field from sexpr to AO_t.
* tests/test.c (a): Do not define (and undefine).
* tests/test.c (a_set, a_get): New macro (that uses AO_store/load).
* tests/test.c (reverse_test_inner): Use a_set() and a_get() to store
and fetch the value of a, respectively; use AO_fetch_and_add1 to
update the value of realloc_count.
* tests/test.c (dropped_something): Change type from int to AO_t.
* tests/test.c (counter): Remove.
* tests/test.c (mktree): Use extra_count instead of counter; use
AO_fetch_and_add1 to update the value of extra_count.
* tests/test.c [GC_PTHREADS && !SMALL_CONFIG && !GC_DEBUG]
(alloc8bytes): Use AO_fetch_and_add1 to update the value of
uncollectable_count.
* tests/test.c (alloc_small, run_one_test): Use AO_fetch_and_add1 to
update the value of atomic_count.
* tests/test.c (tree_test): Use AO_load and AO_store to get and set
the value of dropped_something, respectively.
* tests/test.c (check_heap_stats): Cast uncollectable_count,
atomic_count, stubborn_count, realloc_count to int in printf() call.
Ivan Maidanski [Sun, 8 Oct 2017 10:22:06 +0000 (13:22 +0300)]
Print realloc_count in gctest
Without this patch, realloc_count value is never used.
* tests/test.c (check_heap_stats): Print realloc_count value (after
printing other count variables).
Ivan Maidanski [Sun, 8 Oct 2017 10:09:46 +0000 (13:09 +0300)]
Fix missing atomic_count and realloc_count incrementation in gctest
* tests/test.c [!AT_END && !THREADS] (reverse_test_inner): Increment
realloc_count after GC_REALLOC() call.
* tests/test.c (run_one_test): Increment atomic_count after
(void)GC_MALLOC_ATOMIC(0) and GC_malloc_atomic(1) calls.
Ivan Maidanski [Sun, 8 Oct 2017 09:10:29 +0000 (12:10 +0300)]
Travis CI: Pass --disable-shared option to OS X build with ASan
(fix commit 535cf36)
Ivan Maidanski [Sun, 8 Oct 2017 08:43:32 +0000 (11:43 +0300)]
Fix 'pthread_np.h: no such file' compiler error on kFreeBSD
(fix commit 49d7fe7)
Issue #180 (bdwgc).
* include/private/gcconfig.h [(FREEBSD && __GLIBC__ || LINUX
|| PLATFORM_ANDROID) && !NO_PTHREAD_GETATTR_NP]
(HAVE_PTHREAD_GETATTR_NP): New macro.
* include/private/gcconfig.h [FREEBSD && !__GLIBC__
&& !NO_PTHREAD_ATTR_GET_NP] (HAVE_PTHREAD_NP_H,
HAVE_PTHREAD_ATTR_GET_NP): Likewise.
* os_dep.c [!BEOS && !AMIGA && !OS2 && !MSWIN32 && !MSWINCE
&& !CYGWIN32 && !GC_OPENBSD_THREADS] (include pthread.h,
include pthread_np.h, GC_get_main_stack_base): Check presence of
HAVE_PTHREAD_ATTR_GET_NP, HAVE_PTHREAD_GETATTR_NP, HAVE_PTHREAD_NP_H
macros instead of FREEBSD, NO_PTHREAD_ATTR_GET_NP, LINUX,
PLATFORM_ANDROID, NO_PTHREAD_GETATTR_NP.
* os_dep.c [!HAVE_GET_STACK_BASE] (GC_get_stack_base): Check presence
of THREADS, HAVE_PTHREAD_ATTR_GET_NP, HAVE_PTHREAD_GETATTR_NP,
HAVE_PTHREAD_NP_H macros instead of GC_FREEBSD_THREADS,
NO_PTHREAD_ATTR_GET_NP, GC_LINUX_THREADS, PLATFORM_ANDROID,
NO_PTHREAD_GETATTR_NP, FREEBSD.
Ivan Maidanski [Fri, 6 Oct 2017 18:47:00 +0000 (21:47 +0300)]
Travis CI: Test also 32-bit build with ASan (on OS X, with unmapping)
Ivan Maidanski [Fri, 6 Oct 2017 18:31:35 +0000 (21:31 +0300)]
Travis CI: Test also with Leak Sanitizer (LSan)
Ivan Maidanski [Fri, 6 Oct 2017 18:26:06 +0000 (21:26 +0300)]
Move conditional GC_need_to_lock setting to gc_locks.h
(code refactoring)
* include/private/gc_locks.h [GC_PTHREADS && !THREAD_LOCAL_ALLOC
&& !USE_PTHREAD_LOCKS && !GC_ASSERTIONS] (UNCOND_LOCK): Remove
GC_ASSERT(I_DONT_HOLD_LOCK()) because it is no-op (when assertion
checking is off).
* include/private/gc_locks.h [THREADS] (set_need_to_lock): New macro.
* pthread_support.c [!GC_ALWAYS_MULTITHREADED]
(GC_allow_register_threads, WRAP_FUNC(pthread_create)): Replace
GC_need_to_lock=TRUE to set_need_to_lock().
* win32_threads.c [!GC_ALWAYS_MULTITHREADED]
(GC_allow_register_threads, GC_CreateThread, GC_init_parallel):
Likewise.
* win32_threads.c [!MSWINCE && !CYGWIN32 && !GC_ALWAYS_MULTITHREADED]
(GC_beginthreadex): Likewise.
* win32_threads.c [GC_PTHREADS && !GC_ALWAYS_MULTITHREADED]
(GC_pthread_create): Likewise.
Ivan Maidanski [Fri, 6 Oct 2017 08:14:23 +0000 (11:14 +0300)]
Eliminate TSan warnings for print_proc variables assignment (gctest)
Now GC_is_valid_displacement_print_proc and GC_is_visible_print_proc
are set only once (before the first invocation of run_one_test).
* tests/test.c [DBG_HDRS_ALL] (set_print_procs): New macro (defined
to (void)0).
* tests/test.c [!DBG_HDRS_ALL] (set_print_procs): New function (which
sets GC_is_valid_displacement_print_proc and GC_is_visible_print_proc).
* tests/test.c (fail_count, fail_proc1, TEST_FAIL_COUNT): Do not
define if DBG_HDRS_ALL.
* tests/test.c [!DBG_HDRS_ALL] (run_one_test): Do not set
GC_is_valid_displacement_print_proc and GC_is_visible_print_proc.
* tests/test.c (main): Call set_print_procs() before run_one_test().
* tests/test.c [PCR] (test): Likewise.
Ivan Maidanski [Wed, 27 Sep 2017 23:06:31 +0000 (02:06 +0300)]
Support GC_init (and get_stack_base) from non-main thread on FreeBSD
Issue #180 (bdwgc).
Now GC_get_[main_]stack_base uses pthread_attr_get_np() and
pthread_attr_getstack() to determine the stack base address.
* os_dep.c [FREEBSD && !NO_PTHREAD_ATTR_GET_NP && (THREADS
|| USE_GET_STACKBASE_FOR_MAIN)]: Include pthread.h and pthread_np.h.
* os_dep.c [FREEBSD && !NO_PTHREAD_ATTR_GET_NP
&& (USE_GET_STACKBASE_FOR_MAIN || THREADS && !REDIRECT_MALLOC)]
(GC_get_main_stack_base): Call pthread_attr_init, pthread_attr_get_np
and pthread_attr_getstack to determine the stack base address of the
current thread (fall back to GC_freebsd_main_stack_base in case of
failure).
* os_dep.c [(GC_FREEBSD_THREADS && !NO_PTHREAD_ATTR_GET_NP]
(GC_get_stack_base): Call pthread_attr_init, pthread_attr_get_np and
pthread_attr_getstack to determine the stack base address of the
current thread.
Ivan Maidanski [Wed, 27 Sep 2017 22:46:20 +0000 (01:46 +0300)]
Fix data race in collectable_count (gctest)
* tests/test.c [THREADS && (GC_BUILTIN_ATOMIC || PARALLEL_MARK
|| !GC_WIN32_THREADS)]: Include gc_atomic_ops.h.
* tests/test.c [AO_HAVE_fetch_and_add1] (collectable_count): Change
type to volatile AO_t (and make it static to initalize it without "=0").
* tests/test.c [!AO_HAVE_fetch_and_add1] (AO_fetch_and_add1): Define
to a non-atomic increment (for a single-threaded build).
* tests/test.c (small_cons, reverse_test_inner, mktree, chktree,
alloc8bytes, typed_test, run_one_test): Use
AO_fetch_and_add1(&collectable_count) instead of collectable_count++.
* tests/test.c (check_heap_stats): Cast collectable_count to int in
GC_printf() call.
Ivan Maidanski [Wed, 27 Sep 2017 21:52:40 +0000 (00:52 +0300)]
Fix missing [un]collectable_count increments in gctest
* tests/test.c [!DBG_HDRS_ALL] (run_one_test): Increment
uncollectable_count instead of collectable_count (for
GC_malloc_uncollectable(0)).
* tests/test.c [!DBG_HDRS_ALL] (run_one_test): Add missing increments
of collectable_count for GC_malloc(8) and GC_malloc(17).
* tests/test.c (run_one_test): Add missing increment of
collectable_count for (void)GC_MALLOC(0).
Ivan Maidanski [Wed, 27 Sep 2017 08:42:46 +0000 (11:42 +0300)]
Eliminate '-pedantic is not option that controls warnings' GCC-6.4 message
(fix commits 84c0313, 04eb273)
* mark.c [WRAP_MARK_SOME && (MSWIN32 || MSWINCE) && __GNUC__]
(GC_mark_some): Use "-Wpedantic" instead of "-pedantic" (in pragma
GCC diagnostic) if GCC v6.4+.
Ivan Maidanski [Wed, 27 Sep 2017 08:22:18 +0000 (11:22 +0300)]
Eliminate 'non-null arg compared to null' warning in toggleref_add (GCC)
(fix commit 86991cb)
* finalize.c [!GC_TOGGLE_REFS_NOT_NEEDED] (GC_toggleref_add): Use
NONNULL_ARG_NOT_NULL to check pointer argument marked as non-null (in
the function declaration) is actually non-null.
Ivan Maidanski [Wed, 27 Sep 2017 07:52:09 +0000 (10:52 +0300)]
Fix pthread_detach for threads not yet registered (Cygwin, winpthreads)
* win32_threads.c [GC_PTHREADS] (GC_pthread_detach): Repeat
GC_lookup_pthread() (with a 10 msec delay) while t is null; add comment
and TODO; remove ABORT if t is null (as t is never null after
pthread_detach call).
Ivan Maidanski [Tue, 26 Sep 2017 21:56:14 +0000 (00:56 +0300)]
Fix get_maps on proc maps file asynchronous growth
Issue #179 (bdwgc).
Asynchronous growth of /proc/self/maps could be caused by some thread
which is not currently registered (e.g. stack allocation on thread
creation or a non-GC heap allocation from an unregistered thread).
* os_dep.c [NEED_PROC_MAPS] (GC_get_maps): Refine comment.
* os_dep.c [NEED_PROC_MAPS && THREADS] (GC_get_maps): Replace ABORT
with WARN call; refine printed message; add comment.
Ivan Maidanski [Tue, 26 Sep 2017 08:44:44 +0000 (11:44 +0300)]
Fix pthread_join when thread is registered in thread key destructor
* pthread_support.c (WRAP_FUNC(pthread_join)): Remove assertion that
thread is finished; call GC_delete_gc_thread only if thread is
finished; add comment.
* win32_threads.c [GC_PTHREADS] (GC_pthread_join): Call
GC_delete_gc_thread_no_free and GC_INTERNAL_FREE only if thread is
finished.
Ivan Maidanski [Tue, 26 Sep 2017 08:29:54 +0000 (11:29 +0300)]
Fix pthread_join to avoid thread removal on failure (Cygwin, winpthreads)
* win32_threads.c [GC_WIN32_PTHREADS] (GC_pthread_join): Do not call
GC_lookup_pthread if pthread_join failed.
* win32_threads.c [GC_PTHREADS] (GC_pthread_join): Do not call
GC_delete_gc_thread_no_free, GC_INTERNAL_FREE if pthread_join failed.
* win32_threads.c [GC_PTHREADS && DEBUG_THREADS] (GC_pthread_join):
Log whether pthread_join succeeded or failed.
Ivan Maidanski [Tue, 26 Sep 2017 08:01:29 +0000 (11:01 +0300)]
Fix removal of dead threads in a child process
GC_threads table may contain several elements with the same pthread id,
so GC_remove_all_threads_but_me should remove all elements except for
the first found element matching the id of the current thread.
* pthread_support.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Do not assign me if it is already non-null; add comment.
* win32_threads.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Likewise.
* win32_threads.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Remove GC_ASSERT(me==NULL).
Ivan Maidanski [Mon, 25 Sep 2017 22:12:30 +0000 (01:12 +0300)]
Fix double lock in pthread_detach (Cygwin, winpthreads)
* win32_threads.c [GC_PTHREADS] (GC_pthread_detach): Do not hold the
allocation lock when GC_lookup_pthread is invoked.
Ivan Maidanski [Mon, 25 Sep 2017 21:52:49 +0000 (00:52 +0300)]
Do not disable parallel mark for WRAP_MARK_SOME
Issue #179 (bdwgc).
Now, if there is a chance of unmapping of root segments, the latter
ones are scanned immediately by GC_push_roots thus preventing memory
protection faults in GC_mark_local.
* include/private/gc_priv.h (GC_PUSH_CONDITIONAL): Move definition to
mark_rts.c.
* include/private/gcconfig.h [WRAP_MARK_SOME && PARALLEL_MARK]
(PARALLEL_MARK): Do not undefine; remove TODO item.
* mark.c [WRAP_MARK_SOME && PARALLEL_MARK] (GC_push_conditional_eager):
New internal function; add TODO item.
* mark_rts.c [WRAP_MARK_SOME && PARALLEL_MARK]
(GC_push_conditional_eager): Declare function.
* mark_rts.c [WRAP_MARK_SOME && PARALLEL_MARK] (GC_PUSH_CONDITIONAL):
Define to GC_push_conditional_eager if GC_parallel.
Ivan Maidanski [Fri, 22 Sep 2017 18:37:42 +0000 (21:37 +0300)]
Align local_mark_stack in help_marker explicitly
* mark.c [PARALLEL_MARK] (GC_help_marker): Declare my_id_mse local
variable (of mse type) instead of unsigned my_id; define my_id as
macro to my_id_mse.mse_descr.w; cast my_id to unsigned or int in
GC_helper_count assignment and GC_mark_local() call.
Ivan Maidanski [Tue, 19 Sep 2017 22:23:43 +0000 (01:23 +0300)]
Fix thread id leaks in subthread_create and threadkey_test
* tests/subthread_create.c [GC_PTHREADS] (entry): Call pthread_detach
for the created thread.
* tests/threadkey_test.c (main): Likewise.
* tests/test.c [GC_PTHREADS && CPPCHECK] (main): Remove
UNTESTED(GC_pthread_detach).
* tests/threadkey_test.c (on_thread_exit_inner): New local variable
attr; call pthread_attr_init and pthread_attr_setdetachstate;
pass attr to GC_pthread_create; call pthread_attr_destroy.
Ivan Maidanski [Tue, 19 Sep 2017 22:08:04 +0000 (01:08 +0300)]
Fix missing new-line at format strings end in subthread_create test
* tests/subthread_create.c [GC_PTHREADS] (entry, main): Append "\n" to
fprintf() format string (where missing).
Ivan Maidanski [Tue, 19 Sep 2017 07:51:24 +0000 (10:51 +0300)]
Fix infinite mark_some calls after memory mapping disappeared (Glibc)
Issue #179 (bdwgc).
* mark.c [WRAP_MARK_SOME && REGISTER_LIBRARIES_EARLY] (GC_mark_some):
Call GC_cond_register_dynamic_libraries (with the world running)
before GC_invalidate_mark_state().
Ivan Maidanski [Tue, 19 Sep 2017 07:38:39 +0000 (10:38 +0300)]
Fix 'undefined reference to GC_wait_for_reclaim' linker error
(fix commit f4d690e)
Issue #179 (bdwgc).
* include/private/gc_pmark.h [HAVE_CONFIG_H]: Do not include config.h
if already included from gc_priv.h (to avoid PARALLEL_MARK macro
redefinition in config.h after it was undefined in gcconfig.h).
Ivan Maidanski [Tue, 19 Sep 2017 07:08:38 +0000 (10:08 +0300)]
Add TODO item to suppress 'called on pointer without debugging info'
* dbg_mlc.c [REDIRECT_FREE && USE_PROC_FOR_LIBRARIES] (GC_debug_free):
Add TODO item not to call GC_err_printf() when free() is called from
libpthread or libdl.
Ivan Maidanski [Tue, 19 Sep 2017 06:58:11 +0000 (09:58 +0300)]
Eliminate 'boolean result used in bitwise op' cppcheck false warning
* extra/AmigaOS.c [GC_AMIGA_DS] (GC_register_data_segments):
Replace (ULONG)&data[1] in comparison to (ULONG)(&data[1]).
* misc.c [!THREADS && !SPARC] (GC_do_blocking_inner):
Replace (ptr_t)&d in comparison to (ptr_t)(&d).
Ivan Maidanski [Mon, 18 Sep 2017 22:07:45 +0000 (01:07 +0300)]
Fix USE_GET_STACKBASE_FOR_MAIN definition in gcconfig.h
* include/private/gcconfig.h [PLATFORM_ANDROID && !THREADS]
(USE_GET_STACKBASE_FOR_MAIN): Move definition down to be after THREADS
definition.
Ivan Maidanski [Mon, 18 Sep 2017 21:47:04 +0000 (00:47 +0300)]
Allow custom N_LOCAL_ITERS and ENTRIES_TO_GET values
* mark.c [PARALLEL_MARK] (N_LOCAL_ITERS): Do not define if already
defined.
* mark.c [PARALLEL_MARK] (ENTRIES_TO_GET): Likewise.
Ivan Maidanski [Mon, 18 Sep 2017 21:34:15 +0000 (00:34 +0300)]
Fix missing started_thread_while_stopped call from mark_some if GCC/Clang
* mark.c [WRAP_MARK_SOME && GC_WIN32_THREADS && !GC_PTHREADS]
(GC_started_thread_while_stopped): Declare even if __GNUC__.
* mark.c [WRAP_MARK_SOME && GC_WIN32_THREADS && (MSWIN32 || MSWINCE)]
(GC_mark_some): Invoke GC_started_thread_while_stopped (unless
GC_PTHREADS).
* win32_threads.c [WRAP_MARK_SOME && !GC_PTHREADS]
(GC_started_thread_while_stopped): Define even if __GNUC__.
Ivan Maidanski [Mon, 18 Sep 2017 07:54:37 +0000 (10:54 +0300)]
Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME
Issue #179 (bdwgc).
Parallel marker is disabled (for now) if there is a chance of
scanning unmapped data roots (because GC_do_local_mark is not
prepared to deal with memory protection faults gracefully).
* mark.c [MSWIN32 || USE_PROC_FOR_LIBRARIES] (WRAP_MARK_SOME): Move
definition to gcconfig.h.
* include/private/gcconfig.h [WRAP_MARK_SOME && PARALLEL_MARK]
(PARALLEL_MARK): Undefine (as not implemented yet).
Ivan Maidanski [Wed, 30 Aug 2017 23:12:06 +0000 (02:12 +0300)]
Fix typo in 'scale' documentation file
* doc/scale.md (Options for enhanced scalability): Fix a typo
("be replaced").
Ivan Maidanski [Wed, 30 Aug 2017 07:00:46 +0000 (10:00 +0300)]
Remove unnecessary type casts of printf arguments to unsigned long
(code refactoring)
* alloc.c [!NO_DEBUGGING] (GC_print_heap_sects): Remove unnecessary
cast to unsigned long in GC_*_printf call and adjust printf format
specifier to match the argument type.
* checksums.c [CHECKSUMS] (GC_checksum): Likewise.
* mark.c [PARALLEL_MARK] (GC_mark_local): Likewise.
* tests/test.c (typed_test): Likewise.
* checksums.c [CHECKSUMS] (GC_checksum): Change type of GC_n_clean,
GC_n_dirty from int to unsigned long.
Ivan Maidanski [Tue, 29 Aug 2017 22:17:08 +0000 (01:17 +0300)]
Fix printf arguments type in print_callers
* os_dep.c [NEED_CALLINFO] (GC_print_callers): Cast info[i].ci_pc to
unsigned long in GC_err_printf call to match the format specifier.
Ivan Maidanski [Mon, 28 Aug 2017 08:26:51 +0000 (11:26 +0300)]
Fix assertion violation in return_single_freelist in child process
Issue #171 (bdwgc).
GC_destroy_thread_local cannot be called from a thread other than
the current one.
* pthread_support.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Do not call GC_destroy_thread_local;
add comment.
* win32_threads.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Likewise.
* thread_local_alloc.c [THREAD_LOCAL_ALLOC] (GC_destroy_thread_local):
Update comment.
Ivan Maidanski [Mon, 28 Aug 2017 07:38:18 +0000 (10:38 +0300)]
Travis CI: Test USE_CUSTOM_SPECIFIC
Ivan Maidanski [Mon, 28 Aug 2017 06:27:07 +0000 (09:27 +0300)]
Fix GC_remove_specific invocation from remove_all_threads_but_me
(fix commits fcfae7f, 38e65ea)
* include/private/specific.h (GC_remove_specific): Define as macro
(calls GC_remove_specific_after_fork).
* include/private/specific.h (GC_remove_specific_after_fork): New
GC_INNER function declaration.
* include/private/thread_local_alloc.h [USE_PTHREAD_SPECIFIC
|| USE_COMPILER_TLS || USE_WIN32_COMPILER_TLS || USE_WIN32_SPECIFIC]
(GC_remove_specific_after_fork): New macro (defined to no-op).
* pthread_support.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Call GC_remove_specific_after_fork
instead of GC_remove_specific (i.e. delete thread-specific control data
for the given thread instead of the current one).
* win32_threads.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC] Like
* specific.c [USE_CUSTOM_SPECIFIC] (GC_setspecific): Add assertion that
the allocation lock is held; remove the corresponding comment.
* specific.c [USE_CUSTOM_SPECIFIC] (GC_remove_specific): Replace to
GC_remove_specific_after_fork (add t argument); replace self local
variable with t argument; update comment;
* specific.c [USE_CUSTOM_SPECIFIC && CAN_HANDLE_FORK]
(GC_remove_specific_after_fork): Add assertion that the allocation lock
is held; add comment.
Ivan Maidanski [Fri, 25 Aug 2017 14:59:05 +0000 (17:59 +0300)]
Eliminate 'memory leak' code defect in remove_specific
* specific.c [LINT2] (GC_remove_specific): Call GC_noop1(entry) to
indicate that entry is lost (the memory will be collected during GC).
Ivan Maidanski [Fri, 25 Aug 2017 06:53:07 +0000 (09:53 +0300)]
Simplify THREAD_TABLE_INDEX expression for Win32/64
(fix commit 85fce54)
Windows thread Id rarely has non-zero highest half of DWORD, so
it is OK to use only the lowest one for hash value computation.
* win32_threads.c (THREAD_TABLE_INDEX): Remove (id>>16) from the
expression.
Ivan Maidanski [Thu, 24 Aug 2017 22:05:16 +0000 (01:05 +0300)]
Add debug logging to new_thread about GC_threads hash table collisions
* pthread_support.c [DEBUG_THREADS] (GC_new_thread): Call GC_log_printf
(with the appropriate message) if a GC_threads[] entry already exists
at the given hv index (excluding the detached threads those id is
already reused).
* win32_threads.c [DEBUG_THREADS] (GC_new_thread): Call GC_log_printf
to report that a new thread is created; call GC_log_printf (with the
appropriate message) if a GC_threads[] entry already exists at the
given hv index; remove useless comment about the result of
GC_INTERNAL_MALLOC.
Ivan Maidanski [Thu, 24 Aug 2017 08:34:05 +0000 (11:34 +0300)]
Eliminate most of collisions in GC_threads on Linux/x64
On some targets (e.g., Linux/x64) pthread_t values always have zero
in the lowest byte (e.g. if pthread_t is actually a page-aligned
pointer) thus causing all the created thread descriptors to have
a collision at GC_threads[0]. This commit mixes 3 lowest bytes
of thread id with a XOR operation (thus greatly reduces the
probability of collisions in GC_threads).
* include/private/pthread_support.h (THREAD_TABLE_SZ): Do not
define if already defined; refine comment.
* pthread_support.c (THREAD_TABLE_INDEX): New macro (similar to that
in win32_threads.c).
* pthread_support.c (GC_new_thread, GC_delete_thread,
GC_delete_gc_thread, GC_lookup_thread): Replace
NUMERIC_THREAD_ID(id)%THREAD_TABLE_SZ to THREAD_TABLE_INDEX(id).
* pthread_support.c (GC_lookup_thread): Remove hv local variable.
* win32_threads.c (THREAD_TABLE_INDEX): Replace (id>>2) to
((id>>16)^(id>>8)^id).
* win32_threads.c [GC_PTHREADS] (GC_lookup_pthread): Define win32_id
local variable to pass it to THREAD_TABLE_INDEX() instead of passing
GET_PTHREAD_MAP_CACHE(id) directly.
Ivan Maidanski [Wed, 23 Aug 2017 08:46:41 +0000 (11:46 +0300)]
Change type of THREAD_TABLE_INDEX result to int in win32_threads.c
(code refactoring)
* win32_threads.c (THREAD_TABLE_INDEX): Cast result to int; remove cast
of argument to word type; add comment.
* win32_threads.c (GC_new_thread, GC_delete_gc_thread_no_free,
GC_delete_thread): Change type of hv local variable from word to int.
* win32_threads.c (GC_lookup_thread_inner): Remove hv local variable;
remove "register" keyword for p local variable.
* win32_threads.c (GC_lookup_pthread): Change type of hv_guess local
variable from word to int.
Ivan Maidanski [Tue, 22 Aug 2017 08:23:27 +0000 (11:23 +0300)]
Fix deadlock in GC_help_marker caused by use of mark_cv of parent process
The marker threads of the parent process are blocked on mark_cv at
fork. So pthread_cond_wait() malfunction (hang) is possible in the
child process without mark_cv state cleanup (reinitialization).
* pthread_support.c [PARALLEL_MARK] (mark_cv): Move static variable
definition upper to be before GC_start_mark_threads_inner).
* win32_threads.c [GC_PTHREADS_PARAMARK] (mark_cv): Likewise.
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK] (mark_cv):
Do not initialize statically; add comment.
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK] (mark_cv):
Likewise.
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Initialize mark_cv to
PTHREAD_COND_INITIALIZER (unless available_markers_m1 <= 0 or
GC_parallel); add comment.
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Likewise.
* pthread_support.c [PARALLEL_MARK] (GC_wait_marker,
GC_notify_all_marker): Add assertion that GC_parallel is true (so
mark_cv is initialized).
* win32_threads.c [GC_PTHREADS_PARAMARK] (GC_wait_marker,
GC_notify_all_marker): Likewise.
Ivan Maidanski [Tue, 22 Aug 2017 06:09:04 +0000 (09:09 +0300)]
Travis CI: Test some --enable-munmap configurations with disable incremental collection
Ivan Maidanski [Tue, 22 Aug 2017 05:56:31 +0000 (08:56 +0300)]
Avoid busy waiting in mark_thread while GC_parallel is false
* mark.c [PARALLEL_MARK] (GC_help_marker): Add assertion that
GC_parallel is true (i.e. GC_markers_m1 is non-zero).
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Set GC_markers_m1 value before starting
the first marker thread (it is already set if fork handling is off).
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Likewise.
* pthread_support.c [PARALLEL_MARK] (GC_start_mark_threads_inner):
Adjust GC_markers_m1 value only if pthread_create failed.
* win32_threads.c [GC_PTHREADS_PARAMARK] (GC_start_mark_threads_inner):
Likewise.
Ivan Maidanski [Mon, 21 Aug 2017 22:09:59 +0000 (01:09 +0300)]
Eliminate unsigned fl_builder_count underflow in mark_thread
(refactor commit 0ca6d3f)
* include/private/gc_priv.h [PARALLEL_MARK] (GC_fl_builder_count):
Change type from word to signed_word.
* reclaim.c [PARALLEL_MARK] (GC_fl_builder_count): Likewise.
* mark.c [PARALLEL_MARK] (GC_wait_for_markers_init): Change type of
count local variable to signed_word; add assertion that count is
non-negative.
* pthread_support.c [PARALLEL_MARK] (GC_mark_thread): Add comment that
GC_fl_builder_count can be negative here.
* win32_threads.c [PARALLEL_MARK] (GC_mark_thread): Likewise.
* reclaim.c [PARALLEL_MARK] (GC_fl_builder_count): Refine comment.
Ivan Maidanski [Sat, 19 Aug 2017 15:46:59 +0000 (18:46 +0300)]
Add assertion that no hb_n_marks underflow occurs
Issue #177 (bdwgc).
* alloc.c (GC_clear_fl_marks): Add GC_ASSERT that hhdr->hb_n_marks
is non-zero before decrementing it.
* mark.c (GC_clear_mark_bit): Likewise.
Ivan Maidanski [Sat, 19 Aug 2017 15:22:37 +0000 (18:22 +0300)]
Fix hb_n_marks underflow in clear_fl_marks if MARK_BIT_PER_OBJ
Issue #177 (bdwgc).
* mark.c [MARK_BIT_PER_OBJ] (GC_set_hdr_marks): Set hhdr->hb_n_marks
exactly to n_marks value (without a decrement by one).
Ivan Maidanski [Sat, 19 Aug 2017 14:43:11 +0000 (17:43 +0300)]
Use MARK_BIT_PER_GRANULE instead of MARK_BIT_PER_OBJ where appropriate
(code refactoring)
* allchblk.c (setup_header): Use "ifdef MARK_BIT_PER_GRANULE" instead
of "ifndef MARK_BIT_PER_OBJ".
* mallocx.c (GC_realloc): Likewise.
Ivan Maidanski [Thu, 17 Aug 2017 21:06:37 +0000 (00:06 +0300)]
Update ChangeLog file
Ivan Maidanski [Thu, 17 Aug 2017 20:13:47 +0000 (23:13 +0300)]
Update ChangeLog file (v7.6 changes only)