]> gitweb.factorcode.org Git - factor.git/blob - vm/safepoints.cpp
VM: implement a ctrl-break handler thread (#1573)
[factor.git] / vm / safepoints.cpp
1 #include "master.hpp"
2
3 namespace factor {
4
5 void factor_vm::enqueue_fep() {
6   if (fep_p)
7     fatal_error("Low-level debugger interrupted", 0);
8   atomic::store(&safepoint_fep_p, true);
9   code->set_safepoint_guard(true);
10 }
11
12 void factor_vm::enqueue_samples(cell samples,
13                                 cell pc,
14                                 bool foreign_thread_p) {
15
16   if (!atomic::load(&sampling_profiler_p))
17     return;
18   atomic::fetch_add(&sample_counts.sample_count, samples);
19
20   if (foreign_thread_p)
21     atomic::fetch_add(&sample_counts.foreign_thread_sample_count, samples);
22   else {
23     if (atomic::load(&current_gc_p))
24       atomic::fetch_add(&sample_counts.gc_sample_count, samples);
25     if (atomic::load(&current_jit_count) > 0)
26       atomic::fetch_add(&sample_counts.jit_sample_count, samples);
27     if (!code->seg->in_segment_p(pc))
28       atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
29   }
30   code->set_safepoint_guard(true);
31 }
32
33 void factor_vm::handle_safepoint(cell pc) {
34   code->set_safepoint_guard(false);
35   faulting_p = false;
36
37   if (atomic::load(&safepoint_fep_p)) {
38     atomic::store(&safepoint_fep_p, false);
39     if (atomic::load(&sampling_profiler_p))
40       end_sampling_profiler();
41     std::cout << "Interrupted\n";
42     if (stop_on_ctrl_break) {
43       /* Ctrl-Break throws an exception, interrupting the main thread, same
44          as the "t" command in the factorbug debugger. But for Ctrl-Break to
45          work we don't require the debugger to be activated, or even enabled. */
46       general_error(ERROR_INTERRUPT, false_object, false_object);
47       FACTOR_ASSERT(false);
48     }
49     factorbug();
50   } else if (atomic::load(&sampling_profiler_p)) {
51     FACTOR_ASSERT(code->seg->in_segment_p(pc));
52     code_block* block = code->code_block_for_address(pc);
53     bool prolog_p = block->entry_point() == pc;
54
55     record_sample(prolog_p);
56   }
57 }
58
59 }