mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-16 16:50:21 +02:00
Add thread-local lock-free, TLS-free freelists.
* libguile/bdw-gc.h: Remove a needless compatibility hack. * libguile/gc-inline.h: New file, implementing thread-local freelists providing faster allocation if we already have a scm_i_thread* pointer. Based on gc_inline.h from libgc. * libguile/threads.h (scm_i_thread): Add freelists here. * libguile/threads.c (guilify_self_1, guilify_self_2): Initialize freelists. * libguile/vm.c: Include gc-inline.h. * libguile/vm-engine.c: Rename current_thread to thread. Use scm_inline_cons instead of scm_cons, scm_inline_cell instead of scm_cell, and scm_inline_words instead of words.
This commit is contained in:
parent
407190060b
commit
aef1fcf94e
7 changed files with 247 additions and 30 deletions
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
|
||||
* 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
|
||||
* Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
|
@ -63,6 +63,7 @@
|
|||
#include "libguile/fluids.h"
|
||||
#include "libguile/continuations.h"
|
||||
#include "libguile/gc.h"
|
||||
#include "libguile/gc-inline.h"
|
||||
#include "libguile/init.h"
|
||||
#include "libguile/scmsigs.h"
|
||||
#include "libguile/strings.h"
|
||||
|
@ -95,6 +96,26 @@ thread_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
|
|||
mark_stack_ptr, mark_stack_limit,
|
||||
NULL);
|
||||
|
||||
/* The pointerless freelists are threaded through their first word,
|
||||
but GC doesn't know to trace them (as they are pointerless), so we
|
||||
need to do that here. See the comments at the top of libgc's
|
||||
gc_inline.h. */
|
||||
{
|
||||
size_t n;
|
||||
for (n = 0; n < SCM_INLINE_GC_FREELIST_COUNT; n++)
|
||||
{
|
||||
void *chain = t->pointerless_freelists[n];
|
||||
if (chain)
|
||||
{
|
||||
/* The first link is already marked by the freelist vector,
|
||||
so we just have to mark the tail. */
|
||||
while ((chain = *(void **)chain))
|
||||
mark_stack_ptr = GC_mark_and_push (chain, mark_stack_ptr,
|
||||
mark_stack_limit, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t->vp)
|
||||
mark_stack_ptr = scm_i_vm_mark_stack (t->vp, mark_stack_ptr,
|
||||
mark_stack_limit);
|
||||
|
@ -389,6 +410,8 @@ guilify_self_1 (struct GC_stack_base *base)
|
|||
t.mutexes = SCM_EOL;
|
||||
t.held_mutex = NULL;
|
||||
t.join_queue = SCM_EOL;
|
||||
t.freelists = NULL;
|
||||
t.pointerless_freelists = NULL;
|
||||
t.dynamic_state = SCM_BOOL_F;
|
||||
t.dynstack.base = NULL;
|
||||
t.dynstack.top = NULL;
|
||||
|
@ -459,6 +482,12 @@ guilify_self_2 (SCM parent)
|
|||
t->continuation_root = scm_cons (t->handle, SCM_EOL);
|
||||
t->continuation_base = t->base;
|
||||
|
||||
{
|
||||
size_t size = SCM_INLINE_GC_FREELIST_COUNT * sizeof (void *);
|
||||
t->freelists = scm_gc_malloc (size, "freelists");
|
||||
t->pointerless_freelists = scm_gc_malloc (size, "atomic freelists");
|
||||
}
|
||||
|
||||
if (scm_is_true (parent))
|
||||
t->dynamic_state = scm_make_dynamic_state (parent);
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue