1 #define GRAY_QUEUE_SECTION_SIZE (128 - 3)
2 #define GRAY_QUEUE_LENGTH_LIMIT 64
5 * This is a stack now instead of a queue, so the most recently added items are removed
6 * first, improving cache locality, and keeping the stack size manageable.
8 typedef struct _GrayQueueSection GrayQueueSection;
9 struct _GrayQueueSection {
11 GrayQueueSection *next, *prev;
12 char *objects [GRAY_QUEUE_SECTION_SIZE];
15 static GrayQueueSection *gray_queue_start = NULL;
16 static GrayQueueSection *gray_queue_end = NULL;
18 static int gray_queue_balance = 0;
19 static int num_gray_queue_sections = 0;
22 gray_object_alloc_queue_section (void)
24 GrayQueueSection *section;
26 /* Use the previously allocated queue sections if possible */
27 if (!gray_queue_end && gray_queue_start) {
28 gray_queue_end = gray_queue_start;
29 gray_queue_end->end = 0;
32 if (gray_queue_end && gray_queue_end->next) {
33 gray_queue_end = gray_queue_end->next;
34 gray_queue_end->end = 0;
38 /* Allocate a new section */
39 section = get_internal_mem (sizeof (GrayQueueSection), INTERNAL_MEM_GRAY_QUEUE);
40 ++num_gray_queue_sections;
46 /* Link it with the others */
48 gray_queue_end->next = section;
49 section->prev = gray_queue_end;
51 g_assert (!gray_queue_start);
52 gray_queue_start = section;
54 gray_queue_end = section;
58 gray_object_free_queue_section (GrayQueueSection *section)
60 free_internal_mem (section, INTERNAL_MEM_GRAY_QUEUE);
61 --num_gray_queue_sections;
65 * The following three functions are called in the inner loops of the collector, so they
66 * need to be as fast as possible.
70 gray_object_enqueue (char *obj)
73 if (G_UNLIKELY (!gray_queue_end || gray_queue_end->end == GRAY_QUEUE_SECTION_SIZE))
74 gray_object_alloc_queue_section ();
75 g_assert (gray_queue_end && gray_queue_end->end < GRAY_QUEUE_SECTION_SIZE);
76 gray_queue_end->objects [gray_queue_end->end++] = obj;
81 static inline gboolean
82 gray_object_queue_is_empty (void)
84 return gray_queue_end == NULL;
88 gray_object_dequeue (void)
92 if (gray_object_queue_is_empty ())
95 g_assert (gray_queue_end->end);
97 obj = gray_queue_end->objects [--gray_queue_end->end];
99 if (G_UNLIKELY (gray_queue_end->end == 0))
100 gray_queue_end = gray_queue_end->prev;
102 --gray_queue_balance;
108 gray_object_queue_init (void)
110 GrayQueueSection *section, *next;
113 g_assert (gray_object_queue_is_empty ());
114 g_assert (sizeof (GrayQueueSection) < MAX_FREELIST_SIZE);
115 g_assert (gray_queue_balance == 0);
117 /* Free the extra sections allocated during the last collection */
119 for (section = gray_queue_start; section && i < GRAY_QUEUE_LENGTH_LIMIT; section = section->next)
123 section->prev->next = NULL;
124 for (; section; section = next) {
125 next = section->next;
126 gray_object_free_queue_section (section);