Skip to content
This repository was archived by the owner on Jun 10, 2024. It is now read-only.

Commit ee5b8fe

Browse files
committed
Test that exits are processed without code being run
* Exits that occur in the run Code are processed in the same iteration of the loop. * Exits that occur external to the loop prevent Code from being run at all.
1 parent 9fa5a22 commit ee5b8fe

File tree

3 files changed

+93
-54
lines changed

3 files changed

+93
-54
lines changed

lumen_runtime/src/scheduler.rs

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#[cfg(test)]
2+
pub mod test;
3+
14
use core::fmt::{self, Debug};
25
use core::sync::atomic::{AtomicU64, Ordering};
36

@@ -134,6 +137,8 @@ impl Scheduler {
134137
*arc_process.acquire_heap()
135138
),
136139
}
140+
} else {
141+
arc_process.reduce()
137142
}
138143

139144
match self.run_queues.write().requeue(arc_process) {
@@ -401,57 +406,3 @@ where
401406
{
402407
f(process::test(&process::test_init()))
403408
}
404-
405-
#[cfg(test)]
406-
mod tests {
407-
use super::*;
408-
409-
mod scheduler {
410-
use super::*;
411-
412-
mod new_process {
413-
use super::*;
414-
415-
use liblumen_alloc::erts::process::default_heap;
416-
use liblumen_alloc::erts::term::atom_unchecked;
417-
418-
#[test]
419-
fn different_processes_have_different_pids() {
420-
let erlang = Atom::try_from_str("erlang").unwrap();
421-
let exit = Atom::try_from_str("exit").unwrap();
422-
let normal = atom_unchecked("normal");
423-
let parent_arc_process_control_block = process::test_init();
424-
425-
let first_process_arguments = parent_arc_process_control_block
426-
.list_from_slice(&[normal])
427-
.unwrap();
428-
let (first_heap, first_heap_size) = default_heap().unwrap();
429-
let first_process = Scheduler::spawn_apply_3(
430-
&parent_arc_process_control_block,
431-
erlang,
432-
exit,
433-
first_process_arguments,
434-
first_heap,
435-
first_heap_size,
436-
)
437-
.unwrap();
438-
439-
let second_process_arguments = parent_arc_process_control_block
440-
.list_from_slice(&[normal])
441-
.unwrap();
442-
let (second_heap, second_heap_size) = default_heap().unwrap();
443-
let second_process = Scheduler::spawn_apply_3(
444-
&first_process,
445-
erlang,
446-
exit,
447-
second_process_arguments,
448-
second_heap,
449-
second_heap_size,
450-
)
451-
.unwrap();
452-
453-
assert_ne!(first_process.pid_term(), second_process.pid_term());
454-
}
455-
}
456-
}
457-
}

lumen_runtime/src/scheduler/test.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
mod spawn_apply_3;
2+
3+
use liblumen_alloc::erts::process::code::stack::frame::Placement;
4+
use liblumen_alloc::erts::term::atom_unchecked;
5+
6+
use crate::otp::erlang::exit_1;
7+
use crate::scheduler::{with_process_arc, Scheduler};
8+
9+
#[test]
10+
fn scheduler_does_not_requeue_exiting_process() {
11+
with_process_arc(|arc_process| {
12+
exit_1::place_frame_with_arguments(
13+
&arc_process,
14+
Placement::Replace,
15+
atom_unchecked("normal"),
16+
)
17+
.unwrap();
18+
19+
let scheduler = Scheduler::current();
20+
21+
assert!(scheduler.is_run_queued(&arc_process));
22+
23+
assert!(scheduler.run_through(&arc_process));
24+
25+
assert!(!scheduler.is_run_queued(&arc_process));
26+
})
27+
}
28+
29+
#[test]
30+
fn scheduler_does_run_exiting_process() {
31+
with_process_arc(|arc_process| {
32+
let scheduler = Scheduler::current();
33+
34+
assert!(scheduler.is_run_queued(&arc_process));
35+
assert!(scheduler.run_through(&arc_process));
36+
assert!(scheduler.is_run_queued(&arc_process));
37+
38+
arc_process.exit();
39+
40+
assert!(scheduler.is_run_queued(&arc_process));
41+
assert!(!scheduler.run_through(&arc_process));
42+
assert!(!scheduler.is_run_queued(&arc_process));
43+
})
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use super::*;
2+
3+
use liblumen_alloc::erts::process::default_heap;
4+
use liblumen_alloc::erts::term::{atom_unchecked, Atom};
5+
6+
use crate::process;
7+
8+
#[test]
9+
fn different_processes_have_different_pids() {
10+
let erlang = Atom::try_from_str("erlang").unwrap();
11+
let exit = Atom::try_from_str("exit").unwrap();
12+
let normal = atom_unchecked("normal");
13+
let parent_arc_process_control_block = process::test_init();
14+
15+
let first_process_arguments = parent_arc_process_control_block
16+
.list_from_slice(&[normal])
17+
.unwrap();
18+
let (first_heap, first_heap_size) = default_heap().unwrap();
19+
let first_process = Scheduler::spawn_apply_3(
20+
&parent_arc_process_control_block,
21+
erlang,
22+
exit,
23+
first_process_arguments,
24+
first_heap,
25+
first_heap_size,
26+
)
27+
.unwrap();
28+
29+
let second_process_arguments = parent_arc_process_control_block
30+
.list_from_slice(&[normal])
31+
.unwrap();
32+
let (second_heap, second_heap_size) = default_heap().unwrap();
33+
let second_process = Scheduler::spawn_apply_3(
34+
&first_process,
35+
erlang,
36+
exit,
37+
second_process_arguments,
38+
second_heap,
39+
second_heap_size,
40+
)
41+
.unwrap();
42+
43+
assert_ne!(first_process.pid_term(), second_process.pid_term());
44+
}

0 commit comments

Comments
 (0)