Browse Source

Merge branch 'master' of https://github.com/Meziu/ctru-rs into fix/duplicate-services

pull/50/head
Andrea Ciliberti 3 years ago
parent
commit
5adf2366a6
  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. 1049
      ctru-rs/src/thread.rs

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

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

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

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

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

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

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

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

5
ctru-rs/src/lib.rs

@ -34,7 +34,7 @@ fn _panic_hook_setup() {
use crate::services::hid::{Hid, KeyPad}; use crate::services::hid::{Hid, KeyPad};
use std::panic::PanicInfo; use std::panic::PanicInfo;
let main_thread = thread::current().id(); let main_thread = std::thread::current().id();
// Panic Hook setup // Panic Hook setup
let default_hook = std::panic::take_hook(); let default_hook = std::panic::take_hook();
@ -42,7 +42,7 @@ fn _panic_hook_setup() {
default_hook(info); default_hook(info);
// Only for panics in the main thread // 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"); println!("\nPress SELECT to exit the software");
let hid = Hid::init().unwrap(); let hid = Hid::init().unwrap();
@ -65,7 +65,6 @@ pub mod error;
pub mod gfx; pub mod gfx;
pub mod services; pub mod services;
pub mod srv; pub mod srv;
pub mod thread;
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(all(feature = "romfs", romfs_exists))] { if #[cfg(all(feature = "romfs", romfs_exists))] {

1049
ctru-rs/src/thread.rs

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