X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-gray.h;h=3ea4037af245c7489790da11c2836eae471d4bd0;hb=HEAD;hp=c3b9918763cce796d154b897b3ebb2e56bb86e79;hpb=2971171458de013e82da2fbbf8fefcfcecda2acc;p=mono.git diff --git a/mono/sgen/sgen-gray.h b/mono/sgen/sgen-gray.h index c3b9918763c..3ea4037af24 100644 --- a/mono/sgen/sgen-gray.h +++ b/mono/sgen/sgen-gray.h @@ -1,5 +1,6 @@ -/* - * sgen-gray.h: Gray queue management. +/** + * \file + * Gray queue management. * * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc @@ -41,12 +42,12 @@ /* SGEN_GRAY_QUEUE_HEADER_SIZE is number of machine words */ #ifdef SGEN_CHECK_GRAY_OBJECT_SECTIONS -#define SGEN_GRAY_QUEUE_HEADER_SIZE 4 +#define SGEN_GRAY_QUEUE_HEADER_SIZE 5 #else -#define SGEN_GRAY_QUEUE_HEADER_SIZE 2 +#define SGEN_GRAY_QUEUE_HEADER_SIZE 3 #endif -#define SGEN_GRAY_QUEUE_SECTION_SIZE (128 - SGEN_GRAY_QUEUE_HEADER_SIZE) +#define SGEN_GRAY_QUEUE_SECTION_SIZE (512 - SGEN_GRAY_QUEUE_HEADER_SIZE) #ifdef SGEN_CHECK_GRAY_OBJECT_SECTIONS typedef enum { @@ -65,6 +66,11 @@ struct _GrayQueueEntry { #define SGEN_GRAY_QUEUE_ENTRY(obj,desc) { (obj), (desc) } +#define GRAY_OBJECT_ENQUEUE_SERIAL(queue, obj, desc) (GRAY_OBJECT_ENQUEUE (queue, obj, desc, FALSE)) +#define GRAY_OBJECT_ENQUEUE_PARALLEL(queue, obj, desc) (GRAY_OBJECT_ENQUEUE (queue, obj, desc, TRUE)) +#define GRAY_OBJECT_DEQUEUE_SERIAL(queue, obj, desc) (GRAY_OBJECT_DEQUEUE (queue, obj, desc, FALSE)) +#define GRAY_OBJECT_DEQUEUE_PARALLEL(queue, obj, desc) (GRAY_OBJECT_DEQUEUE (queue, obj, desc, TRUE)) + /* * This is a stack now instead of a queue, so the most recently added items are removed * first, improving cache locality, and keeping the stack size manageable. @@ -80,7 +86,7 @@ struct _GrayQueueSection { GrayQueueSectionState state; #endif int size; - GrayQueueSection *next; + GrayQueueSection *next, *prev; GrayQueueEntry entries [SGEN_GRAY_QUEUE_SECTION_SIZE]; }; @@ -91,9 +97,10 @@ typedef void (*GrayQueueEnqueueCheckFunc) (GCObject*); struct _SgenGrayQueue { GrayQueueEntry *cursor; - GrayQueueSection *first; + GrayQueueSection *first, *last; GrayQueueSection *free_list; - GrayQueueAllocPrepareFunc alloc_prepare_func; + mono_mutex_t steal_mutex; + gint32 num_sections; #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE GrayQueueEnqueueCheckFunc enqueue_check_func; #endif @@ -124,16 +131,17 @@ extern guint64 stat_gray_queue_dequeue_slow_path; void sgen_init_gray_queues (void); -void sgen_gray_object_enqueue (SgenGrayQueue *queue, GCObject *obj, SgenDescriptor desc); -GrayQueueEntry sgen_gray_object_dequeue (SgenGrayQueue *queue); +void sgen_gray_object_enqueue (SgenGrayQueue *queue, GCObject *obj, SgenDescriptor desc, gboolean is_parallel); +GrayQueueEntry sgen_gray_object_dequeue (SgenGrayQueue *queue, gboolean is_parallel); GrayQueueSection* sgen_gray_object_dequeue_section (SgenGrayQueue *queue); -void sgen_gray_object_enqueue_section (SgenGrayQueue *queue, GrayQueueSection *section); +GrayQueueSection* sgen_gray_object_steal_section (SgenGrayQueue *queue); +void sgen_gray_object_spread (SgenGrayQueue *queue, int num_sections); +void sgen_gray_object_enqueue_section (SgenGrayQueue *queue, GrayQueueSection *section, gboolean is_parallel); void sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue); -void sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func); -void sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue); -void sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func); +void sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func, gboolean reuse_free_list); +void sgen_gray_object_queue_dispose (SgenGrayQueue *queue); void sgen_gray_object_queue_deinit (SgenGrayQueue *queue); -void sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue); +void sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue, gboolean is_parallel); void sgen_gray_object_free_queue_section (GrayQueueSection *section); void sgen_section_gray_queue_init (SgenSectionGrayQueue *queue, gboolean locked, @@ -151,13 +159,13 @@ sgen_gray_object_queue_is_empty (SgenGrayQueue *queue) } static inline MONO_ALWAYS_INLINE void -GRAY_OBJECT_ENQUEUE (SgenGrayQueue *queue, GCObject *obj, SgenDescriptor desc) +GRAY_OBJECT_ENQUEUE (SgenGrayQueue *queue, GCObject *obj, SgenDescriptor desc, gboolean is_parallel) { #if SGEN_MAX_DEBUG_LEVEL >= 9 - sgen_gray_object_enqueue (queue, obj, desc); + sgen_gray_object_enqueue (queue, obj, desc, is_parallel); #else if (G_UNLIKELY (!queue->first || queue->cursor == GRAY_LAST_CURSOR_POSITION (queue->first))) { - sgen_gray_object_enqueue (queue, obj, desc); + sgen_gray_object_enqueue (queue, obj, desc, is_parallel); } else { GrayQueueEntry entry = SGEN_GRAY_QUEUE_ENTRY (obj, desc); @@ -172,11 +180,11 @@ GRAY_OBJECT_ENQUEUE (SgenGrayQueue *queue, GCObject *obj, SgenDescriptor desc) } static inline MONO_ALWAYS_INLINE void -GRAY_OBJECT_DEQUEUE (SgenGrayQueue *queue, GCObject** obj, SgenDescriptor *desc) +GRAY_OBJECT_DEQUEUE (SgenGrayQueue *queue, GCObject** obj, SgenDescriptor *desc, gboolean is_parallel) { GrayQueueEntry entry; #if SGEN_MAX_DEBUG_LEVEL >= 9 - entry = sgen_gray_object_dequeue (queue); + entry = sgen_gray_object_dequeue (queue, is_parallel); *obj = entry.obj; *desc = entry.desc; #else @@ -185,7 +193,7 @@ GRAY_OBJECT_DEQUEUE (SgenGrayQueue *queue, GCObject** obj, SgenDescriptor *desc) *obj = NULL; } else if (G_UNLIKELY (queue->cursor == GRAY_FIRST_CURSOR_POSITION (queue->first))) { - entry = sgen_gray_object_dequeue (queue); + entry = sgen_gray_object_dequeue (queue, is_parallel); *obj = entry.obj; *desc = entry.desc; } else {