Try to make the :lurking-threads test more robust.
[sbcl.git] / src / runtime / dynbind.c
blob78895e0d53f9fddf7cbf5a5918eb67906784de06
1 /*
2 * support for dynamic binding from C
3 * See the "Chapter 9: Specials" of the SBCL Internals Manual.
4 */
6 /*
7 * This software is part of the SBCL system. See the README file for
8 * more information.
10 * This software is derived from the CMU CL system, which was
11 * written at Carnegie Mellon University and released into the
12 * public domain. The software is in the public domain and is
13 * provided with absolutely no warranty. See the COPYING and CREDITS
14 * files for more information.
17 #include <stdio.h>
18 #include <stdlib.h>
20 #include "sbcl.h"
21 #include "runtime.h"
22 #include "globals.h"
23 #include "dynbind.h"
24 #include "thread.h"
25 #include "interr.h"
26 #include "genesis/symbol.h"
27 #include "genesis/binding.h"
29 /* Specially bind SYMBOL to VALUE. In a multithreaded build, SYMBOL must already
30 have been assigned a thread-local storage index. See *KNOWN-TLS-SYMBOLS* in
31 compiler/generic/genesis for the symbols whose indices are pre-assigned. */
32 #ifdef LISP_FEATURE_SB_THREAD
33 #define value_address(thing, thread) \
34 (lispobj*)(thing + (char*)((union per_thread_data *)thread)->dynamic_values)
35 void bind_tls_cell(unsigned symbol, lispobj value, void *th)
36 #else
37 #define value_address(thing, thread) &SYMBOL(thing)->value
38 void bind_variable(lispobj symbol, lispobj value, void *th)
39 #endif
41 struct binding *binding;
42 __attribute__((unused)) struct thread *thread = (struct thread *)th;
43 binding = (struct binding *)get_binding_stack_pointer(thread);
44 set_binding_stack_pointer(thread,binding+1);
45 binding->symbol = symbol;
46 lispobj* where = value_address(symbol, thread);
47 binding->value = *where;
48 *where = value;
51 void
52 unbind(void *th)
54 __attribute__((unused)) struct thread *thread = (struct thread *)th;
55 struct binding *binding;
57 binding = ((struct binding *)get_binding_stack_pointer(thread)) - 1;
59 /* On sb-thread, 'binding->symbol' is actually a tls-index */
60 *value_address(binding->symbol, thread) = binding->value;
62 binding->symbol = 0;
63 binding->value = 0;
65 set_binding_stack_pointer(thread,binding);
68 void
69 unbind_to_here(lispobj *bsp,void *th)
71 __attribute__((unused)) struct thread *thread = (struct thread *)th;
72 struct binding *target = (struct binding *)bsp;
73 struct binding *binding = (struct binding *)get_binding_stack_pointer(thread);
74 lispobj symbol;
76 while (target < binding) {
77 binding--;
79 symbol = binding->symbol;
80 if (symbol) {
81 if (symbol != UNBOUND_MARKER_WIDETAG) {
82 *value_address(symbol, thread) = binding->value;
84 binding->symbol = 0;
85 binding->value = 0;
88 set_binding_stack_pointer(thread,binding);