(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.
GC_INNER void GC_notify_all_builder(void);
GC_INNER void GC_wait_for_reclaim(void);
- GC_EXTERN word GC_fl_builder_count; /* Protected by mark lock. */
+ GC_EXTERN signed_word GC_fl_builder_count; /* Protected by mark lock. */
GC_INNER void GC_notify_all_marker(void);
GC_INNER void GC_wait_marker(void);
/* marker_[b]sp, marker_mach_threads, GC_marker_Id). */
GC_INNER void GC_wait_for_markers_init(void)
{
- word count;
+ signed_word count;
if (GC_markers_m1 == 0)
return;
/* Reuse marker lock and builders count to synchronize */
/* marker threads startup. */
GC_acquire_mark_lock();
- GC_fl_builder_count += (word)GC_markers_m1;
+ GC_fl_builder_count += GC_markers_m1;
count = GC_fl_builder_count;
GC_release_mark_lock();
- if (count != 0)
+ if (count != 0) {
+ GC_ASSERT(count > 0);
GC_wait_for_reclaim();
+ }
}
/* Steal mark stack entries starting at mse low into mark stack local */
/* Inform GC_start_mark_threads about completion of marker data init. */
GC_acquire_mark_lock();
- if (0 == --GC_fl_builder_count)
+ if (0 == --GC_fl_builder_count) /* count may have a negative value */
GC_notify_all_builder();
GC_release_mark_lock();
/* on free lists which we had to drop. */
#if defined(PARALLEL_MARK)
- GC_INNER word GC_fl_builder_count = 0;
+ GC_INNER signed_word GC_fl_builder_count = 0;
/* Number of threads currently building free lists without */
/* holding GC lock. It is not safe to collect if this is */
- /* nonzero. */
+ /* nonzero. Also, together with the mark lock, it is used as */
+ /* a semaphore during marker threads startup. */
#endif /* PARALLEL_MARK */
/* We defer printing of leaked objects until we're done with the GC */
/* Inform GC_start_mark_threads about completion of marker data init. */
GC_acquire_mark_lock();
- if (0 == --GC_fl_builder_count)
+ if (0 == --GC_fl_builder_count) /* count may have a negative value */
GC_notify_all_builder();
GC_release_mark_lock();