1
Fork 0
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:
Andy Wingo 2014-02-02 16:04:58 +01:00
parent 407190060b
commit aef1fcf94e
7 changed files with 247 additions and 30 deletions

View file

@ -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