static void rehash (SgenHashTable *hash_table) { SgenHashTableEntry **old_hash = hash_table->table; guint old_hash_size = hash_table->size; guint i, hash, new_size; SgenHashTableEntry **new_hash; SgenHashTableEntry *entry, *next; if (!old_hash) { sgen_register_fixed_internal_mem_type (hash_table->entry_mem_type, sizeof (SgenHashTableEntry*) + sizeof (gpointer) + hash_table->data_size); new_size = 13; } else { new_size = g_spaced_primes_closest (hash_table->num_entries); } new_hash = sgen_alloc_internal_dynamic (new_size * sizeof (SgenHashTableEntry*), hash_table->table_mem_type); for (i = 0; i < old_hash_size; ++i) { for (entry = old_hash [i]; entry; entry = next) { hash = hash_table->hash_func (entry->key) % new_size; next = entry->next; entry->next = new_hash [hash]; new_hash [hash] = entry; } } sgen_free_internal_dynamic (old_hash, old_hash_size * sizeof (SgenHashTableEntry*), hash_table->table_mem_type); hash_table->table = new_hash; hash_table->size = new_size; }
void sgen_init_nursery_allocator (void) { sgen_register_fixed_internal_mem_type (INTERNAL_MEM_FRAGMENT, sizeof (SgenFragment)); #ifdef NALLOC_DEBUG alloc_records = sgen_alloc_os_memory (sizeof (AllocRecord) * ALLOC_RECORD_COUNT, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "debugging memory"); #endif }
void sgen_tarjan_bridge_init (SgenBridgeProcessor *collector) { collector->reset_data = reset_data; collector->processing_stw_step = processing_stw_step; collector->processing_build_callback_data = processing_build_callback_data; collector->processing_after_callback = processing_after_callback; collector->class_kind = class_kind; collector->register_finalized_object = register_finalized_object; collector->describe_pointer = describe_pointer; collector->enable_accounting = enable_accounting; // collector->set_dump_prefix = set_dump_prefix; sgen_register_fixed_internal_mem_type (INTERNAL_MEM_TARJAN_OBJ_BUCKET, BUCKET_SIZE); g_assert (sizeof (ObjectBucket) <= BUCKET_SIZE); g_assert (sizeof (ColorBucket) <= BUCKET_SIZE); bridge_processor = collector; }
void sgen_workers_init (int num_workers) { int i; if (!sgen_get_major_collector ()->is_parallel) return; //g_print ("initing %d workers\n", num_workers); workers_num = num_workers; workers_data = sgen_alloc_internal_dynamic (sizeof (WorkerData) * num_workers, INTERNAL_MEM_WORKER_DATA, TRUE); memset (workers_data, 0, sizeof (WorkerData) * num_workers); MONO_SEM_INIT (&workers_waiting_sem, 0); MONO_SEM_INIT (&workers_done_sem, 0); sgen_gray_object_queue_init_with_alloc_prepare (&workers_distribute_gray_queue, workers_gray_queue_share_redirect, &workers_gc_thread_data); mono_mutex_init (&workers_gc_thread_data.stealable_stack_mutex, NULL); workers_gc_thread_data.stealable_stack_fill = 0; if (sgen_get_major_collector ()->alloc_worker_data) workers_gc_thread_data.major_collector_data = sgen_get_major_collector ()->alloc_worker_data (); for (i = 0; i < workers_num; ++i) { /* private gray queue is inited by the thread itself */ mono_mutex_init (&workers_data [i].stealable_stack_mutex, NULL); workers_data [i].stealable_stack_fill = 0; if (sgen_get_major_collector ()->alloc_worker_data) workers_data [i].major_collector_data = sgen_get_major_collector ()->alloc_worker_data (); } LOCK_INIT (workers_job_queue_mutex); sgen_register_fixed_internal_mem_type (INTERNAL_MEM_JOB_QUEUE_ENTRY, sizeof (JobQueueEntry)); mono_counters_register ("Stolen from self lock", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_workers_stolen_from_self_lock); mono_counters_register ("Stolen from self no lock", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_workers_stolen_from_self_no_lock); mono_counters_register ("Stolen from others", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_workers_stolen_from_others); mono_counters_register ("# workers waited", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_workers_num_waited); }
void sgen_workers_init (int num_workers) { int i; if (!sgen_get_major_collector ()->is_concurrent) return; //g_print ("initing %d workers\n", num_workers); workers_num = num_workers; workers_data = sgen_alloc_internal_dynamic (sizeof (WorkerData) * num_workers, INTERNAL_MEM_WORKER_DATA, TRUE); memset (workers_data, 0, sizeof (WorkerData) * num_workers); MONO_SEM_INIT (&workers_waiting_sem, 0); MONO_SEM_INIT (&workers_done_sem, 0); init_distribute_gray_queue (sgen_get_major_collector ()->is_concurrent); if (sgen_get_major_collector ()->alloc_worker_data) workers_gc_thread_major_collector_data = sgen_get_major_collector ()->alloc_worker_data (); for (i = 0; i < workers_num; ++i) { workers_data [i].index = i; if (sgen_get_major_collector ()->alloc_worker_data) workers_data [i].major_collector_data = sgen_get_major_collector ()->alloc_worker_data (); } LOCK_INIT (workers_job_queue_mutex); sgen_register_fixed_internal_mem_type (INTERNAL_MEM_JOB_QUEUE_ENTRY, sizeof (JobQueueEntry)); mono_counters_register ("Stolen from self lock", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_workers_stolen_from_self_lock); mono_counters_register ("Stolen from self no lock", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_workers_stolen_from_self_no_lock); mono_counters_register ("Stolen from others", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_workers_stolen_from_others); mono_counters_register ("# workers waited", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_workers_num_waited); }