De-flake 'traceroot' test
[sbcl.git] / src / runtime / dynbind.c
blob08626ed2553292059c28e77f76040c8e86ab8d7b
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 void bind_variable(lispobj symbol, lispobj value, void *th)
34 struct binding *binding;
35 struct thread *thread=(struct thread *)th;
36 binding = (struct binding *)get_binding_stack_pointer(thread);
37 set_binding_stack_pointer(thread,binding+1);
38 #ifdef LISP_FEATURE_SB_THREAD
40 struct symbol *sym=(struct symbol *)native_pointer(symbol);
41 // We could provide a c-callable static Lisp function to assign TLS
42 // indices if anyone really needs dynamic binding of dynamic symbols.
43 binding->symbol = tls_index_of(sym);
44 if(!binding->symbol)
45 lose("Oops! Static symbol missing from *KNOWN-TLS-SYMBOLS*");
46 binding->value = SymbolTlValue(symbol, thread);
48 #else
49 binding->symbol = symbol;
50 binding->value = SymbolTlValue(symbol, thread);
51 #endif
52 SetTlSymbolValue(symbol, value, thread);
55 void
56 unbind(void *th)
58 struct thread *thread=(struct thread *)th;
59 struct binding *binding;
60 lispobj symbol;
62 binding = ((struct binding *)get_binding_stack_pointer(thread)) - 1;
64 /* On sb-thread, it's actually a tls-index */
65 symbol = binding->symbol;
67 #ifdef LISP_FEATURE_SB_THREAD
69 ((union per_thread_data *)thread)->dynamic_values[(symbol) >> WORD_SHIFT]
70 = binding->value;
71 #else
72 SetSymbolValue(symbol, binding->value, thread);
73 #endif
75 binding->symbol = 0;
76 binding->value = 0;
78 set_binding_stack_pointer(thread,binding);
81 void
82 unbind_to_here(lispobj *bsp,void *th)
84 struct thread *thread=(struct thread *)th;
85 struct binding *target = (struct binding *)bsp;
86 struct binding *binding = (struct binding *)get_binding_stack_pointer(thread);
87 lispobj symbol;
89 while (target < binding) {
90 binding--;
92 symbol = binding->symbol;
93 if (symbol) {
94 if (symbol != UNBOUND_MARKER_WIDETAG) {
95 #ifdef LISP_FEATURE_SB_THREAD
96 ((union per_thread_data *)thread)->dynamic_values[(symbol) >> WORD_SHIFT]
97 = binding->value;
98 #else
99 SetSymbolValue(symbol, binding->value, thread);
100 #endif
102 binding->symbol = 0;
103 binding->value = 0;
106 set_binding_stack_pointer(thread,binding);