mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
system: Implement thread priority setting
This commit is contained in:
@@ -175,6 +175,7 @@ validator = [
|
|||||||
"randomx",
|
"randomx",
|
||||||
"smol",
|
"smol",
|
||||||
|
|
||||||
|
"blockchain",
|
||||||
"system",
|
"system",
|
||||||
"wasm-runtime",
|
"wasm-runtime",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ pub use publisher::{Publisher, PublisherPtr, Subscription};
|
|||||||
pub mod timeout;
|
pub mod timeout;
|
||||||
pub use timeout::io_timeout;
|
pub use timeout::io_timeout;
|
||||||
|
|
||||||
|
/// Thread priority setting
|
||||||
|
pub mod thread_priority;
|
||||||
|
|
||||||
pub type ExecutorPtr = Arc<Executor<'static>>;
|
pub type ExecutorPtr = Arc<Executor<'static>>;
|
||||||
|
|
||||||
/// Sleep for any number of seconds.
|
/// Sleep for any number of seconds.
|
||||||
|
|||||||
127
src/system/thread_priority.rs
Normal file
127
src/system/thread_priority.rs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/* This file is part of DarkFi (https://dark.fi)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2025 Dyne.org foundation
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Levels of thread priority
|
||||||
|
pub enum ThreadPriority {
|
||||||
|
Min,
|
||||||
|
Low,
|
||||||
|
Normal,
|
||||||
|
High,
|
||||||
|
Max,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set current thread priority to given `priority`.
|
||||||
|
/// This usually requires root privileges.
|
||||||
|
pub fn set_thread_priority(priority: ThreadPriority) {
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
type HANDLE = *mut std::ffi::c_void;
|
||||||
|
|
||||||
|
const THREAD_PRIORITY_IDLE: i32 = -15;
|
||||||
|
const THREAD_PRIORITY_BELOW_NORMAL: i32 = -1;
|
||||||
|
const THREAD_PRIORITY_NORMAL: i32 = 0;
|
||||||
|
const THREAD_PRIORITY_ABOVE_NORMAL: i32 = 1;
|
||||||
|
const THREAD_PRIORITY_TIME_CRITICAL: i32 = 15;
|
||||||
|
|
||||||
|
extern "system" {
|
||||||
|
fn GetCurrentThread() -> HANDLE;
|
||||||
|
fn SetThreadPriority(hThread: HANDLE, nPriority: i32) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
let priority_value = match priority {
|
||||||
|
ThreadPriority::Min => THREAD_PRIORITY_IDLE,
|
||||||
|
ThreadPriority::Low => THREAD_PRIORITY_BELOW_NORMAL,
|
||||||
|
ThreadPriority::Normal => THREAD_PRIORITY_NORMAL,
|
||||||
|
ThreadPriority::High => THREAD_PRIORITY_ABOVE_NORMAL,
|
||||||
|
ThreadPriority::Max => THREAD_PRIORITY_TIME_CRITICAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SetThreadPriority(GetCurrentThread(), priority_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
extern "C" {
|
||||||
|
fn setpriority(which: i32, who: u32, prio: i32) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PRIO_PROCESS: i32 = 0;
|
||||||
|
|
||||||
|
let nice_value = match priority {
|
||||||
|
ThreadPriority::Min => 19,
|
||||||
|
ThreadPriority::Low => 10,
|
||||||
|
ThreadPriority::Normal => 0,
|
||||||
|
ThreadPriority::High => -10,
|
||||||
|
ThreadPriority::Max => -20,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
setpriority(PRIO_PROCESS, std::process::id(), nice_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
|
{
|
||||||
|
type mach_port_t = u32;
|
||||||
|
type thread_t = mach_port_t;
|
||||||
|
type thread_policy_flavor_t = i32;
|
||||||
|
type thread_policy_t = *mut i32;
|
||||||
|
type mach_msg_type_number_t = u32;
|
||||||
|
|
||||||
|
const THREAD_PRECEDENCE_POLICY: thread_policy_flavor_t = 3;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct thread_precedence_policy_data {
|
||||||
|
importance: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn mach_thread_self() -> thread_t;
|
||||||
|
fn thread_policy_set(
|
||||||
|
thread: thread_t,
|
||||||
|
flavor: thread_policy_flavor_t,
|
||||||
|
policy_info: thread_policy_t,
|
||||||
|
count: mach_msg_type_number_t,
|
||||||
|
) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
let importance = match priority {
|
||||||
|
ThreadPriority::Min => -30,
|
||||||
|
ThreadPriority::Low => -15,
|
||||||
|
ThreadPriority::Normal => 0,
|
||||||
|
ThreadPriority::High => 15,
|
||||||
|
ThreadPriority::Max => 30,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let thread = mach_thread_self();
|
||||||
|
let mut policy = thread_precedence_policy_data { importance };
|
||||||
|
let count =
|
||||||
|
std::mem::size_of::<thread_precedence_policy_data>() as mach_msg_type_number_t / 4;
|
||||||
|
|
||||||
|
thread_policy_set(
|
||||||
|
thread,
|
||||||
|
THREAD_PRECEDENCE_POLICY,
|
||||||
|
&mut policy as *mut _ as thread_policy_t,
|
||||||
|
count,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ use crate::{
|
|||||||
block_store::{BlockDifficulty, BlockInfo},
|
block_store::{BlockDifficulty, BlockInfo},
|
||||||
Blockchain, BlockchainOverlayPtr,
|
Blockchain, BlockchainOverlayPtr,
|
||||||
},
|
},
|
||||||
|
system::thread_priority::ThreadPriority,
|
||||||
util::{ringbuffer::RingBuffer, time::Timestamp},
|
util::{ringbuffer::RingBuffer, time::Timestamp},
|
||||||
validator::{randomx_factory::init_dataset_wrapper, utils::median},
|
validator::{randomx_factory::init_dataset_wrapper, utils::median},
|
||||||
Error, Result,
|
Error, Result,
|
||||||
@@ -380,9 +381,15 @@ pub fn mine_block(
|
|||||||
let dataset = if threads > 1 {
|
let dataset = if threads > 1 {
|
||||||
let a = (dataset_item_count * (t as u32)) / (threads as u32);
|
let a = (dataset_item_count * (t as u32)) / (threads as u32);
|
||||||
let b = (dataset_item_count * (t as u32 + 1)) / (threads as u32);
|
let b = (dataset_item_count * (t as u32 + 1)) / (threads as u32);
|
||||||
init_dataset_wrapper(flags, cache.clone(), a, b - a)?
|
init_dataset_wrapper(flags, cache.clone(), a, b - a, ThreadPriority::Normal)?
|
||||||
} else {
|
} else {
|
||||||
init_dataset_wrapper(flags, cache.clone(), 0, dataset_item_count)?
|
init_dataset_wrapper(
|
||||||
|
flags,
|
||||||
|
cache.clone(),
|
||||||
|
0,
|
||||||
|
dataset_item_count,
|
||||||
|
ThreadPriority::Normal,
|
||||||
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let stop_signal = stop_signal.clone();
|
let stop_signal = stop_signal.clone();
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ use std::{
|
|||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use randomx::{RandomXCache, RandomXDataset, RandomXFlags, RandomXVM};
|
use randomx::{RandomXCache, RandomXDataset, RandomXFlags, RandomXVM};
|
||||||
|
|
||||||
use crate::Result;
|
use crate::{
|
||||||
|
system::thread_priority::{set_thread_priority, ThreadPriority},
|
||||||
|
Result,
|
||||||
|
};
|
||||||
|
|
||||||
/// Wrapper for creating a [`RandomXDataset`]
|
/// Wrapper for creating a [`RandomXDataset`]
|
||||||
pub fn init_dataset_wrapper(
|
pub fn init_dataset_wrapper(
|
||||||
@@ -35,17 +38,9 @@ pub fn init_dataset_wrapper(
|
|||||||
cache: RandomXCache,
|
cache: RandomXCache,
|
||||||
start_item: u32,
|
start_item: u32,
|
||||||
item_count: u32,
|
item_count: u32,
|
||||||
/* priority: i32, */
|
priority: ThreadPriority,
|
||||||
) -> Result<RandomXDataset> {
|
) -> Result<RandomXDataset> {
|
||||||
/* set_thread_priority(priority); */
|
set_thread_priority(priority);
|
||||||
|
|
||||||
/*
|
|
||||||
if (is_x86_feature_detected!("avx2") && item_count % 5) {
|
|
||||||
let dataset = RandomXDataset::new(flags, cache, start_item, item_count - (item_count % 5))?;
|
|
||||||
let dataset = RandomXDataset::new(flags, cache, start_item + item_count - 5, 5)?;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ok(RandomXDataset::new(flags, cache, start_item, item_count)?)
|
Ok(RandomXDataset::new(flags, cache, start_item, item_count)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user