static gboolean workers_dequeue_and_do_job (WorkerData *data) { JobQueueEntry *entry; /* * At this point the GC might not be running anymore. We * could have been woken up by a job that was then taken by * another thread, after which the collection finished, so we * first have to successfully dequeue a job before doing * anything assuming that the collection is still ongoing. */ if (!workers_job_queue_num_entries) return FALSE; mono_mutex_lock (&workers_job_queue_mutex); entry = (JobQueueEntry*)workers_job_queue; if (entry) { workers_job_queue = entry->next; --workers_job_queue_num_entries; } mono_mutex_unlock (&workers_job_queue_mutex); if (!entry) return FALSE; g_assert (collection_needs_workers ()); entry->func (data, entry->data); sgen_free_internal (entry, INTERNAL_MEM_JOB_QUEUE_ENTRY); SGEN_ATOMIC_ADD (workers_num_jobs_finished, 1); return TRUE; }
void sgen_gray_object_free_queue_section (GrayQueueSection *section) { sgen_free_internal (section, INTERNAL_MEM_GRAY_QUEUE); }
static void sgen_ssb_finish_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) { int i; SgenThreadInfo *info; RememberedSet *remset; GenericStoreRememberedSet *store_remset; mword *p; #ifdef HEAVY_STATISTICS remset_stats (); #endif /* the generic store ones */ store_remset = generic_store_remsets; while (store_remset) { GenericStoreRememberedSet *next = store_remset->next; for (i = 0; i < STORE_REMSET_BUFFER_SIZE - 1; ++i) { gpointer addr = store_remset->data [i]; if (addr) handle_remset ((mword*)&addr, start_nursery, end_nursery, FALSE, queue); } sgen_free_internal (store_remset, INTERNAL_MEM_STORE_REMSET); store_remset = next; } generic_store_remsets = NULL; /* the per-thread ones */ FOREACH_THREAD (info) { RememberedSet *next; int j; for (remset = info->remset; remset; remset = next) { SGEN_LOG (4, "Scanning remset for thread %p, range: %p-%p, size: %td", info, remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) p = handle_remset (p, start_nursery, end_nursery, FALSE, queue); remset->store_next = remset->data; next = remset->next; remset->next = NULL; if (remset != info->remset) { SGEN_LOG (4, "Freed remset at %p", remset->data); sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET); } } for (j = 0; j < *info->store_remset_buffer_index_addr; ++j) handle_remset ((mword*)*info->store_remset_buffer_addr + j + 1, start_nursery, end_nursery, FALSE, queue); clear_thread_store_remset_buffer (info); } END_FOREACH_THREAD /* the freed thread ones */ while (freed_thread_remsets) { RememberedSet *next; remset = freed_thread_remsets; SGEN_LOG (4, "Scanning remset for freed thread, range: %p-%p, size: %td", remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) p = handle_remset (p, start_nursery, end_nursery, FALSE, queue); next = remset->next; SGEN_LOG (4, "Freed remset at %p", remset->data); sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET); freed_thread_remsets = next; } }