-/*
- * sgen-memory-governor.c: When to schedule collections based on
- * memory usage.
+/**
+ * \file
+ * When to schedule collections based on memory usage.
*
* Author:
* Rodrigo Kumpera (rkumpera@novell.com)
#include "mono/sgen/sgen-gc.h"
#include "mono/sgen/sgen-memory-governor.h"
-#include "mono/sgen/sgen-thread-pool.h"
+#include "mono/sgen/sgen-workers.h"
#include "mono/sgen/sgen-client.h"
-#define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(DEFAULT_NURSERY_SIZE * default_allowance_nursery_size_ratio))
+#define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(SGEN_DEFAULT_NURSERY_SIZE * default_allowance_nursery_size_ratio))
static SgenPointerQueue log_entries = SGEN_POINTER_QUEUE_INIT (INTERNAL_MEM_TEMPORARY);
-static MonoCoopMutex log_entries_mutex;
+static mono_mutex_t log_entries_mutex;
mword total_promoted_size = 0;
mword total_allocated_major = 0;
/* FIXME: Why is this here? */
if (major_collector.free_swept_blocks)
- major_collector.free_swept_blocks (allowance);
+ major_collector.free_swept_blocks (major_collector.get_num_major_sections () * SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO);
major_collection_trigger_size = new_heap_size + allowance;
static void
sgen_add_log_entry (SgenLogEntry *log_entry)
{
- mono_coop_mutex_lock (&log_entries_mutex);
+ mono_os_mutex_lock (&log_entries_mutex);
sgen_pointer_queue_add (&log_entries, log_entry);
- mono_coop_mutex_unlock (&log_entries_mutex);
+ mono_os_mutex_unlock (&log_entries_mutex);
}
void
switch (entry->type) {
case SGEN_LOG_NURSERY:
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MINOR%s: (%s) time %.2fms, %s promoted %dK major size: %dK in use: %dK los size: %dK in use: %dK",
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MINOR%s: (%s) time %.2fms, %s promoted %zdK major size: %zdK in use: %zdK los size: %zdK in use: %zdK",
entry->is_overflow ? "_OVERFLOW" : "",
entry->reason ? entry->reason : "",
entry->time / 10000.0f,
entry->los_size_in_use / 1024);
break;
case SGEN_LOG_MAJOR_SERIAL:
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR%s: (%s) time %.2fms, %s los size: %dK in use: %dK",
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR%s: (%s) time %.2fms, %s los size: %zdK in use: %zdK",
entry->is_overflow ? "_OVERFLOW" : "",
entry->reason ? entry->reason : "",
(int)entry->time / 10000.0f,
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR_CONCURRENT_START: (%s)", entry->reason ? entry->reason : "");
break;
case SGEN_LOG_MAJOR_CONC_FINISH:
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR_CONCURRENT_FINISH: (%s) time %.2fms, %s los size: %dK in use: %dK",
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR_CONCURRENT_FINISH: (%s) time %.2fms, %s los size: %zdK in use: %zdK",
entry->reason ? entry->reason : "",
entry->time / 10000.0f,
full_timing_buff,
entry->los_size_in_use / 1024);
break;
case SGEN_LOG_MAJOR_SWEEP_FINISH:
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR_SWEEP: major size: %dK in use: %dK",
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR_SWEEP: major size: %zdK in use: %zdK",
entry->major_size / 1024,
entry->major_size_in_use / 1024);
break;
if (mono_trace_is_traced (G_LOG_LEVEL_INFO, MONO_TRACE_GC)) {
size_t i;
SGEN_ASSERT (0, !sgen_is_world_stopped (), "We can't log if the world is stopped");
- mono_coop_mutex_lock (&log_entries_mutex);
+ mono_os_mutex_lock (&log_entries_mutex);
for (i = 0; i < log_entries.next_slot; i++) {
sgen_output_log_entry (log_entries.data [i], stw_time, generation);
sgen_free_internal (log_entries.data [i], INTERNAL_MEM_LOG_ENTRY);
}
sgen_pointer_queue_clear (&log_entries);
- mono_coop_mutex_unlock (&log_entries_mutex);
+ mono_os_mutex_unlock (&log_entries_mutex);
}
}
* This must not require any lock.
*/
void*
-sgen_alloc_os_memory (size_t size, SgenAllocFlags flags, const char *assert_description)
+sgen_alloc_os_memory (size_t size, SgenAllocFlags flags, const char *assert_description, MonoMemAccountType type)
{
void *ptr;
g_assert (!(flags & ~(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE)));
- ptr = mono_valloc (0, size, prot_flags_for_activate (flags & SGEN_ALLOC_ACTIVATE));
+ ptr = mono_valloc (0, size, prot_flags_for_activate (flags & SGEN_ALLOC_ACTIVATE), type);
sgen_assert_memory_alloc (ptr, size, assert_description);
if (ptr) {
SGEN_ATOMIC_ADD_P (total_alloc, size);
}
/* size must be a power of 2 */
+// FIXME: remove assert_description
void*
-sgen_alloc_os_memory_aligned (size_t size, mword alignment, SgenAllocFlags flags, const char *assert_description)
+sgen_alloc_os_memory_aligned (size_t size, mword alignment, SgenAllocFlags flags, const char *assert_description, MonoMemAccountType type)
{
void *ptr;
g_assert (!(flags & ~(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE)));
- ptr = mono_valloc_aligned (size, alignment, prot_flags_for_activate (flags & SGEN_ALLOC_ACTIVATE));
+ ptr = mono_valloc_aligned (size, alignment, prot_flags_for_activate (flags & SGEN_ALLOC_ACTIVATE), type);
sgen_assert_memory_alloc (ptr, size, assert_description);
if (ptr) {
SGEN_ATOMIC_ADD_P (total_alloc, size);
* Free the memory returned by sgen_alloc_os_memory (), returning it to the OS.
*/
void
-sgen_free_os_memory (void *addr, size_t size, SgenAllocFlags flags)
+sgen_free_os_memory (void *addr, size_t size, SgenAllocFlags flags, MonoMemAccountType type)
{
g_assert (!(flags & ~SGEN_ALLOC_HEAP));
- mono_vfree (addr, size);
+ mono_vfree (addr, size, type);
SGEN_ATOMIC_ADD_P (total_alloc, -(gssize)size);
total_alloc_max = MAX (total_alloc_max, total_alloc);
}
sgen_memgov_try_alloc_space (mword size, int space)
{
if (sgen_memgov_available_free_space () < size) {
- SGEN_ASSERT (4, !sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()), "Memory shouldn't run out in worker thread");
+ SGEN_ASSERT (4, !sgen_workers_is_worker_thread (mono_native_thread_id_get ()), "Memory shouldn't run out in worker thread");
return FALSE;
}
debug_print_allowance = debug_allowance;
major_collection_trigger_size = MIN_MINOR_COLLECTION_ALLOWANCE;
- mono_counters_register ("Memgov alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE, &total_alloc);
- mono_counters_register ("Memgov max alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_MONOTONIC, &total_alloc_max);
+ mono_counters_register ("Memgov alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE, (void*)&total_alloc);
+ mono_counters_register ("Memgov max alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_MONOTONIC, (void*)&total_alloc_max);
- mono_coop_mutex_init (&log_entries_mutex);
+ mono_os_mutex_init (&log_entries_mutex);
sgen_register_fixed_internal_mem_type (INTERNAL_MEM_LOG_ENTRY, sizeof (SgenLogEntry));
max_heap = soft_limit;
}
- if (max_heap < sgen_nursery_size * 4) {
+ if (max_heap < SGEN_DEFAULT_NURSERY_SIZE * 4) {
sgen_env_var_error (MONO_GC_PARAMS_NAME, "Setting to minimum.", "`max-heap-size` must be at least 4 times as large as `nursery size`.");
- max_heap = sgen_nursery_size * 4;
+ max_heap = SGEN_DEFAULT_NURSERY_SIZE * 4;
}
- max_heap_size = max_heap - sgen_nursery_size;
+ max_heap_size = max_heap - SGEN_DEFAULT_NURSERY_SIZE;
if (allowance_ratio)
default_allowance_nursery_size_ratio = allowance_ratio;