Browse Source

Merge pull request #46 from Meziu/feature/std-threads

Use std threads support
pull/52/head
Meziu 3 years ago committed by GitHub
parent
commit
df845c5b8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      ctru-rs/examples/futures-basic.rs
  2. 9
      ctru-rs/examples/futures-tokio.rs
  3. 11
      ctru-rs/examples/thread-basic.rs
  4. 104
      ctru-rs/examples/thread-info.rs
  5. 7
      ctru-rs/examples/thread-locals.rs
  6. 5
      ctru-rs/src/lib.rs
  7. 5
      ctru-rs/src/test_runner.rs
  8. 1049
      ctru-rs/src/thread.rs

7
ctru-rs/examples/futures-basic.rs

@ -5,11 +5,14 @@ @@ -5,11 +5,14 @@
//! The example also implements clean shutdown by using a oneshot channel to end the future, thus
//! ending the executor and the thread it runs on.
#![feature(horizon_thread_ext)]
use ctru::console::Console;
use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
use futures::StreamExt;
use std::os::horizon::thread::BuilderExt;
fn main() {
ctru::init();
@ -26,8 +29,8 @@ fn main() { @@ -26,8 +29,8 @@ fn main() {
let (exit_sender, mut exit_receiver) = futures::channel::oneshot::channel();
let (mut timer_sender, mut timer_receiver) = futures::channel::mpsc::channel(0);
let executor_thread = ctru::thread::Builder::new()
.affinity(1)
let executor_thread = std::thread::Builder::new()
.processor_id(1)
.spawn(move || {
let mut executor = futures::executor::LocalPool::new();

9
ctru-rs/examples/futures-tokio.rs

@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
#![feature(horizon_thread_ext)]
use ctru::console::Console;
use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
use std::os::horizon::thread::BuilderExt;
use std::time::Duration;
fn main() {
@ -23,11 +26,9 @@ fn main() { @@ -23,11 +26,9 @@ fn main() {
.build()
.expect("Couldn't build runtime");
let runtime_thread = ctru::thread::Builder::new()
let runtime_thread = std::thread::Builder::new()
// Run on the system core
.affinity(1)
// Use a bigger stack size. Default is 0x1000 but we'd easily overflow that.
.stack_size(0x200000)
.processor_id(1)
.spawn(move || {
runtime.block_on(async move {
let mut wake_time = tokio::time::Instant::now() + Duration::from_secs(1);

11
ctru-rs/examples/thread-basic.rs

@ -1,9 +1,10 @@ @@ -1,9 +1,10 @@
#![feature(horizon_thread_ext)]
use ctru::console::Console;
use ctru::gfx::Gfx;
use ctru::services::apt::Apt;
use ctru::services::hid::{Hid, KeyPad};
use ctru::thread;
use std::os::horizon::thread::BuilderExt;
use std::time::Duration;
fn main() {
@ -14,11 +15,11 @@ fn main() { @@ -14,11 +15,11 @@ fn main() {
let gfx = Gfx::default();
let _console = Console::init(gfx.top_screen.borrow_mut());
let prio = thread::current().priority();
let prio = std::os::horizon::thread::current_priority();
println!("Main thread prio: {}\n", prio);
for ix in 0..3 {
thread::Builder::new()
std::thread::Builder::new()
.priority(prio - 1)
.spawn(move || {
let sleep_duration: u64 = 1000 + ix * 250;
@ -26,7 +27,7 @@ fn main() { @@ -26,7 +27,7 @@ fn main() {
loop {
println!("Thread{ix} says {i}");
i += 1;
thread::sleep(Duration::from_millis(sleep_duration));
std::thread::sleep(Duration::from_millis(sleep_duration));
}
})
.unwrap();

104
ctru-rs/examples/thread-info.rs

@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
//! Prints some interesting system info about the main and (spawned) system threads.
#![feature(horizon_thread_ext)]
use ctru::console::Console;
use ctru::gfx::Gfx;
use ctru::services::apt::Apt;
use ctru::services::hid::{Hid, KeyPad};
use std::os::horizon::thread::BuilderExt;
fn main() {
ctru::init();
let gfx = Gfx::default();
let hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
.expect("Failed to enable system core");
print_processor("main thread");
print_thread_id("main thread");
print_priority("main thread");
print_affinity_mask("main thread");
std::thread::Builder::new()
.processor_id(1)
.spawn(|| {
print_processor("sys thread");
print_thread_id("sys thread");
print_priority("sys thread");
print_affinity_mask("sys thread");
})
.unwrap()
.join()
.unwrap();
println!("sys thread exited");
println!("\nPress Start to exit");
while apt.main_loop() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
break;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}
fn print_processor(thread_name: &str) {
println!(
"{thread_name} processor: {}",
std::os::horizon::thread::current_processor()
);
}
fn print_priority(thread_name: &str) {
println!(
"{thread_name} priority: {:#x}",
std::os::horizon::thread::current_priority()
);
}
fn print_affinity_mask(thread_name: &str) {
let mut affinity_mask = [0u8; 1];
let result = unsafe {
ctru_sys::svcGetThreadAffinityMask(
affinity_mask.as_mut_ptr(),
ctru_sys::CUR_THREAD_HANDLE,
2,
)
};
if ctru_sys::R_FAILED(result) {
println!("Error getting affinity mask:");
println!("result level = {}", ctru_sys::R_LEVEL(result));
println!("result summary = {}", ctru_sys::R_SUMMARY(result));
println!("result description = {}", ctru_sys::R_DESCRIPTION(result));
return;
}
let affinity_value = affinity_mask[0];
println!("{thread_name} affinity: {affinity_value:#x?}");
}
fn print_thread_id(thread_name: &str) {
let mut thread_id = 0;
let result = unsafe { ctru_sys::svcGetThreadId(&mut thread_id, ctru_sys::CUR_THREAD_HANDLE) };
if ctru_sys::R_FAILED(result) {
println!("Error getting thread ID:");
println!("result level = {}", ctru_sys::R_LEVEL(result));
println!("result summary = {}", ctru_sys::R_SUMMARY(result));
println!("result description = {}", ctru_sys::R_DESCRIPTION(result));
return;
}
println!("{thread_name} ID: {thread_id:#x?}")
}

7
ctru-rs/examples/thread-locals.rs

@ -1,8 +1,11 @@ @@ -1,8 +1,11 @@
#![feature(horizon_thread_ext)]
use ctru::console::Console;
use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
use std::cell::RefCell;
use std::os::horizon::thread::BuilderExt;
std::thread_local! {
static MY_LOCAL: RefCell<&'static str> = RefCell::new("initial value");
@ -28,8 +31,8 @@ fn main() { @@ -28,8 +31,8 @@ fn main() {
println!("Value on main thread after mutation: {}", local.borrow());
});
ctru::thread::Builder::new()
.affinity(1)
std::thread::Builder::new()
.processor_id(1)
.spawn(move || {
MY_LOCAL.with(|local| {
println!("Initial value on second thread: {}", local.borrow());

5
ctru-rs/src/lib.rs

@ -28,7 +28,7 @@ pub fn init() { @@ -28,7 +28,7 @@ pub fn init() {
use std::panic::PanicInfo;
let main_thread = thread::current().id();
let main_thread = std::thread::current().id();
// Panic Hook setup
let default_hook = std::panic::take_hook();
@ -36,7 +36,7 @@ pub fn init() { @@ -36,7 +36,7 @@ pub fn init() {
default_hook(info);
// Only for panics in the main thread
if main_thread == thread::current().id() && console::Console::exists() {
if main_thread == std::thread::current().id() && console::Console::exists() {
println!("\nPress SELECT to exit the software");
let hid = services::hid::Hid::init().unwrap();
@ -57,7 +57,6 @@ pub mod error; @@ -57,7 +57,6 @@ pub mod error;
pub mod gfx;
pub mod services;
pub mod srv;
pub mod thread;
cfg_if::cfg_if! {
if #[cfg(all(feature = "romfs", romfs_exists))] {

5
ctru-rs/src/test_runner.rs

@ -115,9 +115,4 @@ mod link_fix { @@ -115,9 +115,4 @@ mod link_fix {
extern "C" fn sigemptyset(_arg1: *mut libc::sigset_t) -> ::libc::c_int {
-1
}
#[no_mangle]
extern "C" fn sysconf(_name: libc::c_int) -> libc::c_long {
-1
}
}

1049
ctru-rs/src/thread.rs

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save