Use uvth for background tasks

This commit is contained in:
Imbris 2021-03-17 01:15:17 -04:00
parent 75944d19eb
commit 9a4110dbf0
23 changed files with 164 additions and 78 deletions

53
Cargo.lock generated
View File

@ -223,7 +223,7 @@ checksum = "792c2eca2af86c76ffd3e72ca564c33b5a5551d5ac3f4f87dce8c0b7c6434061"
dependencies = [
"ahash 0.7.2",
"bincode",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"log",
"notify 4.0.15",
"parking_lot 0.11.1",
@ -1021,13 +1021,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd01a6eb3daaafa260f6fc94c3a6c36390abc2080e38e3e34ced87393fb77d80"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"crossbeam-deque 0.8.0",
"crossbeam-epoch 0.9.3",
"crossbeam-queue",
"crossbeam-utils 0.8.3",
]
[[package]]
name = "crossbeam-channel"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
dependencies = [
"crossbeam-utils 0.6.6",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.0"
@ -1098,6 +1107,16 @@ dependencies = [
"crossbeam-utils 0.8.3",
]
[[package]]
name = "crossbeam-utils"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
dependencies = [
"cfg-if 0.1.10",
"lazy_static",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
@ -2107,7 +2126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac2c82074cafb68b9e459c50c655f7eedcb92d6ee7166813802934bc6fc29fa3"
dependencies = [
"ab_glyph",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"crossbeam-deque 0.8.0",
"linked-hash-map",
"rayon",
@ -3183,7 +3202,7 @@ checksum = "e5fd82b93434edb9c00ae65ee741e0e081cdc8c63346ab9f687935a629aaf4c3"
dependencies = [
"anymap",
"bitflags",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"filetime",
"fsevent 2.0.2",
"fsevent-sys 3.0.2",
@ -4020,7 +4039,7 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
dependencies = [
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"crossbeam-deque 0.8.0",
"crossbeam-utils 0.8.3",
"lazy_static",
@ -5057,7 +5076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9965507e507f12c8901432a33e31131222abac31edd90cabbcf85cf544b7127a"
dependencies = [
"chrono",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"tracing-subscriber",
]
@ -5299,6 +5318,17 @@ dependencies = [
"serde",
]
[[package]]
name = "uvth"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e5910f9106b96334c6cae1f1d77a764bda66ac4ca9f507f73259f184fe1bb6b"
dependencies = [
"crossbeam-channel 0.3.9",
"log",
"num_cpus",
]
[[package]]
name = "vcpkg"
version = "0.2.11"
@ -5345,6 +5375,7 @@ dependencies = [
"tokio",
"tracing",
"tracing-subscriber",
"uvth",
"vek",
"veloren-common",
"veloren-common-base",
@ -5362,7 +5393,7 @@ dependencies = [
"arraygen",
"assets_manager",
"criterion",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"crossbeam-utils 0.8.3",
"csv",
"dot_vox",
@ -5465,7 +5496,7 @@ dependencies = [
"bytes",
"clap",
"criterion",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"futures-core",
"futures-util",
"lazy_static",
@ -5531,7 +5562,7 @@ version = "0.9.0"
dependencies = [
"authc",
"chrono",
"crossbeam-channel",
"crossbeam-channel 0.5.0",
"diesel",
"diesel_migrations",
"dotenv",
@ -5555,6 +5586,7 @@ dependencies = [
"specs-idvs",
"tokio",
"tracing",
"uvth",
"vek",
"veloren-common",
"veloren-common-base",
@ -5574,6 +5606,7 @@ dependencies = [
"clap",
"crossterm 0.19.0",
"lazy_static",
"num_cpus",
"ron",
"serde",
"signal-hook 0.3.7",
@ -5583,6 +5616,7 @@ dependencies = [
"tracing-subscriber",
"tracing-tracy",
"tui",
"uvth",
"veloren-common",
"veloren-common-base",
"veloren-common-net",
@ -5644,6 +5678,7 @@ dependencies = [
"tracing-subscriber",
"tracing-tracy",
"treeculler",
"uvth",
"vek",
"veloren-client",
"veloren-common",

View File

@ -30,6 +30,7 @@ specs = { git = "https://github.com/amethyst/specs.git", rev = "5a9b71035007be0e
vek = { version = "=0.14.1", features = ["serde"] }
hashbrown = { version = "0.9", features = ["rayon", "serde", "nightly"] }
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "fb3dcbc4962b367253f8f2f92760ef44d2679c9a" }
uvth = "4.0.1"
#bot only
async-channel = { version = "1.6", optional = true }

View File

@ -138,6 +138,7 @@ pub struct Client {
registered: bool,
presence: Option<PresenceKind>,
runtime: Arc<Runtime>,
background_threadpool: Arc<uvth::ThreadPool>,
server_info: ServerInfo,
world_data: WorldData,
player_list: HashMap<Uid, PlayerInfo>,
@ -197,6 +198,7 @@ impl Client {
addr: ConnectionArgs,
view_distance: Option<u32>,
runtime: Arc<Runtime>,
background_threadpool: Arc<uvth::ThreadPool>,
) -> Result<Self, Error> {
let network = Network::new(Pid::new(), &runtime);
@ -443,6 +445,7 @@ impl Client {
registered: false,
presence: None,
runtime,
background_threadpool,
server_info,
world_data: WorldData {
lod_base,
@ -1850,12 +1853,14 @@ impl Client {
* 1000.0
}
/// Get a reference to the client's runtime thread pool. This pool should be
/// used for any computationally expensive operations that run outside
/// of the main thread (i.e., threads that block on I/O operations are
/// exempt).
/// Get a reference to the client's async runtime.
pub fn runtime(&self) -> &Arc<Runtime> { &self.runtime }
/// Get a reference to the client's background task threadpool.
/// This pool should be used for any computationally expensive operations that run outside
/// of the main thread (i.e., threads that block on I/O operations are exempt).
pub fn background_threadpool(&self) -> &Arc<uvth::ThreadPool> { &self.background_threadpool }
/// Get a reference to the client's game state.
pub fn state(&self) -> &State { &self.state }

View File

@ -61,7 +61,7 @@ pub mod resources;
#[cfg(not(target_arch = "wasm32"))] pub mod rtsim;
#[cfg(not(target_arch = "wasm32"))]
pub mod skillset_builder;
pub mod slowjob;
//pub mod slowjob;
#[cfg(not(target_arch = "wasm32"))]
pub mod spiral;
#[cfg(not(target_arch = "wasm32"))]

View File

@ -11,7 +11,6 @@ use common::{
outcome::Outcome,
region::RegionMap,
resources::{DeltaTime, GameMode, PlayerEntity, Time, TimeOfDay},
slowjob::SlowJobPool,
terrain::{Block, TerrainChunk, TerrainGrid},
time::DayPeriod,
trade::Trades,
@ -129,7 +128,7 @@ impl State {
.unwrap(),
);
Self {
ecs: Self::setup_ecs_world(game_mode, &thread_pool),
ecs: Self::setup_ecs_world(game_mode),
thread_pool,
}
}
@ -137,7 +136,7 @@ impl State {
/// Creates ecs world and registers all the common components and resources
// TODO: Split up registering into server and client (e.g. move
// EventBus<ServerEvent> to the server)
fn setup_ecs_world(game_mode: GameMode, thread_pool: &Arc<ThreadPool>) -> specs::World {
fn setup_ecs_world(game_mode: GameMode) -> specs::World {
let mut ecs = specs::World::new();
// Uids for sync
ecs.register_sync_marker();
@ -227,10 +226,10 @@ impl State {
ecs.insert(game_mode);
ecs.insert(Vec::<common::outcome::Outcome>::new());
let slow_limit = thread_pool.current_num_threads().max(2) as u64;
let slow_limit = slow_limit / 2 + slow_limit / 4;
tracing::trace!(?slow_limit, "Slow Thread limit");
ecs.insert(SlowJobPool::new(slow_limit, Arc::clone(&thread_pool)));
//let slow_limit = thread_pool.current_num_threads().max(2) as u64;
//let slow_limit = slow_limit / 2 + slow_limit / 4;
//tracing::trace!(?slow_limit, "Slow Thread limit");
//ecs.insert(SlowJobPool::new(slow_limit, Arc::clone(&thread_pool)));
// TODO: only register on the server
ecs.insert(EventBus::<ServerEvent>::default());
@ -344,7 +343,7 @@ impl State {
pub fn terrain(&self) -> Fetch<TerrainGrid> { self.ecs.read_resource() }
/// Get a reference to this state's terrain.
pub fn slow_job_pool(&self) -> Fetch<SlowJobPool> { self.ecs.read_resource() }
//pub fn slow_job_pool(&self) -> Fetch<SlowJobPool> { self.ecs.read_resource() }
/// Get a writable reference to this state's terrain.
pub fn terrain_mut(&self) -> FetchMut<TerrainGrid> { self.ecs.write_resource() }

View File

@ -27,6 +27,8 @@ tracing = { version = "0.1", default-features = false }
tracing-subscriber = { version = "0.2.3", default-features = false, features = ["env-filter", "fmt", "chrono", "ansi", "smallvec"] }
ron = {version = "0.6", default-features = false}
serde = {version = "1.0", features = [ "rc", "derive" ]}
uvth = "4.0.1"
num_cpus = "1.0"
# Tracy
tracing-tracy = { version = "0.6.0", optional = true }

View File

@ -108,6 +108,14 @@ fn main() -> io::Result<()> {
.unwrap(),
);
let cores = num_cpus::get();
let background_threadpool = Arc::new(
uvth::ThreadPoolBuilder::new()
.num_threads(cores.max(2) / 2 + cores / 4)
.name("background_threadpool".into())
.build(),
);
// Load server settings
let mut server_settings = server::Settings::load(&server_data_dir);
let mut editable_settings = server::EditableSettings::load(&server_data_dir);
@ -152,6 +160,7 @@ fn main() -> io::Result<()> {
editable_settings,
&server_data_dir,
runtime,
background_threadpool,
)
.expect("Failed to create server instance!");

View File

@ -49,6 +49,7 @@ diesel = { version = "1.4.3", features = ["sqlite"] }
diesel_migrations = "1.4.0"
dotenv = "0.15.0"
slab = "0.4"
uvth = "4.0.1"
# Plugins
plugin-api = { package = "veloren-plugin-api", path = "../plugin/api"}

View File

@ -1,7 +1,7 @@
use crate::metrics::ChunkGenMetrics;
#[cfg(not(feature = "worldgen"))]
use crate::test_world::{IndexOwned, World};
use common::{generation::ChunkSupplement, slowjob::SlowJobPool, terrain::TerrainChunk};
use common::{generation::ChunkSupplement, terrain::TerrainChunk};
use hashbrown::{hash_map::Entry, HashMap};
use specs::Entity as EcsEntity;
use std::sync::{
@ -39,7 +39,8 @@ impl ChunkGenerator {
&mut self,
entity: Option<EcsEntity>,
key: Vec2<i32>,
slowjob_pool: &SlowJobPool,
//slowjob_pool: &SlowJobPool,
background_threadpool: &uvth::ThreadPool,
world: Arc<World>,
index: IndexOwned,
) {
@ -52,7 +53,8 @@ impl ChunkGenerator {
v.insert(Arc::clone(&cancel));
let chunk_tx = self.chunk_tx.clone();
self.metrics.chunks_requested.inc();
slowjob_pool.spawn("CHUNK_GENERATOR", move || {
//slowjob_pool.spawn("CHUNK_GENERATOR", move || {
background_threadpool.execute(move || {
let index = index.as_index_ref();
let payload = world
.generate_chunk(index, key, || cancel.load(Ordering::Relaxed))

View File

@ -63,7 +63,6 @@ use common::{
recipe::default_recipe_book,
resources::TimeOfDay,
rtsim::RtSimEntity,
slowjob::SlowJobPool,
terrain::TerrainChunkSize,
uid::UidAllocator,
};
@ -137,6 +136,7 @@ pub struct Server {
connection_handler: ConnectionHandler,
runtime: Arc<Runtime>,
background_threadpool: Arc<uvth::ThreadPool>,
metrics_shutdown: Arc<Notify>,
}
@ -150,6 +150,7 @@ impl Server {
editable_settings: EditableSettings,
data_dir: &std::path::Path,
runtime: Arc<Runtime>,
background_threadpool: Arc<uvth::ThreadPool>,
) -> Result<Self, Error> {
info!("Server is data dir is: {}", data_dir.display());
if settings.auth_server_address.is_none() {
@ -196,10 +197,10 @@ impl Server {
state.ecs_mut().insert(ecs_system_metrics);
state.ecs_mut().insert(tick_metrics);
state.ecs_mut().insert(physics_metrics);
state
.ecs_mut()
.write_resource::<SlowJobPool>()
.configure("CHUNK_GENERATOR", |n| n / 2 + n / 4);
//state
// .ecs_mut()
// .write_resource::<SlowJobPool>()
// .configure("CHUNK_GENERATOR", |n| n / 2 + n / 4);
state
.ecs_mut()
.insert(ChunkGenerator::new(chunk_gen_metrics));
@ -368,6 +369,7 @@ impl Server {
connection_handler,
runtime,
background_threadpool,
metrics_shutdown,
};
@ -629,7 +631,8 @@ impl Server {
let index = &mut self.index;
let world = &mut self.world;
let ecs = self.state.ecs_mut();
let slow_jobs = ecs.write_resource::<SlowJobPool>();
//let slow_jobs = ecs.write_resource::<SlowJobPool>();
let background_threadpool = &self.background_threadpool;
index.reload_colors_if_changed(|index| {
let mut chunk_generator = ecs.write_resource::<ChunkGenerator>();
@ -648,7 +651,8 @@ impl Server {
chunk_generator.generate_chunk(
None,
pos,
&slow_jobs,
//&slow_jobs,
&background_threadpool,
Arc::clone(&world),
index.clone(),
);
@ -790,11 +794,12 @@ impl Server {
pub fn generate_chunk(&mut self, entity: EcsEntity, key: Vec2<i32>) {
let ecs = self.state.ecs();
let slow_jobs = ecs.write_resource::<SlowJobPool>();
//let slow_jobs = ecs.write_resource::<SlowJobPool>();
ecs.write_resource::<ChunkGenerator>().generate_chunk(
Some(entity),
key,
&slow_jobs,
//&slow_jobs,
&self.background_threadpool,
Arc::clone(&self.world),
self.index.clone(),
);
@ -982,7 +987,7 @@ impl Server {
// rng.gen_range(-e/2..e/2 + 1));
let pos = comp::Pos(Vec3::from(world_dims_blocks.map(|e| e as f32 / 2.0)));
self.state
.create_persister(pos, view_distance, &self.world, &self.index)
.create_persister(pos, view_distance, &self.world, &self.index, &self.background_threadpool)
.build();
}
}

View File

@ -11,7 +11,6 @@ use common::{
Inventory,
},
effect::Effect,
slowjob::SlowJobPool,
uid::{Uid, UidAllocator},
};
use common_net::{
@ -80,6 +79,7 @@ pub trait StateExt {
view_distance: u32,
world: &std::sync::Arc<world::World>,
index: &world::IndexOwned,
background_threadpool: &uvth::ThreadPool,
) -> EcsEntityBuilder;
/// Insert common/default components for a new character joining the server
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId);
@ -324,13 +324,14 @@ impl StateExt for State {
view_distance: u32,
world: &std::sync::Arc<world::World>,
index: &world::IndexOwned,
background_threadpool: &uvth::ThreadPool,
) -> EcsEntityBuilder {
use common::{terrain::TerrainChunkSize, vol::RectVolSize};
use std::sync::Arc;
// Request chunks
{
let ecs = self.ecs();
let slow_jobs = ecs.write_resource::<SlowJobPool>();
//let slow_jobs = ecs.write_resource::<SlowJobPool>();
let mut chunk_generator =
ecs.write_resource::<crate::chunk_generator::ChunkGenerator>();
let chunk_pos = self.terrain().pos_key(pos.0.map(|e| e as i32));
@ -348,7 +349,7 @@ impl StateExt for State {
* TerrainChunkSize::RECT_SIZE.x as f64
})
.for_each(|chunk_key| {
chunk_generator.generate_chunk(None, chunk_key, &slow_jobs, Arc::clone(world), index.clone());
chunk_generator.generate_chunk(None, chunk_key, /*&slow_jobs,*/ background_threadpool, Arc::clone(world), index.clone());
});
}

View File

@ -88,6 +88,7 @@ num_cpus = "1.0"
# vec_map = { version = "0.8.2" }
inline_tweak = "1.0.2"
itertools = "0.10.0"
uvth = "4.0.1"
# Tracy
tracing-tracy = { version = "0.6.0", optional = true }

View File

@ -2,7 +2,7 @@ pub mod comp;
pub mod sys;
use crate::audio::sfx::SfxEventItem;
use common::{event::EventBus, slowjob::SlowJobPool};
use common::event::EventBus;
use specs::{World, WorldExt};
pub fn init(world: &mut World) {
@ -10,9 +10,9 @@ pub fn init(world: &mut World) {
world.register::<comp::Interpolated>();
{
let pool = world.read_resource::<SlowJobPool>();
pool.configure("FIGURE_MESHING", |n| n / 2);
pool.configure("TERRAIN_MESHING", |n| n / 2);
//let pool = world.read_resource::<SlowJobPool>();
//pool.configure("FIGURE_MESHING", |n| n / 2);
//pool.configure("TERRAIN_MESHING", |n| n / 2);
}
// Voxygen event buses

View File

@ -148,7 +148,8 @@ impl PlayState for CharSelectionState {
time: client.state().get_time(),
delta_time: client.state().ecs().read_resource::<DeltaTime>().0,
tick: client.get_tick(),
slow_job_pool: &client.state().slow_job_pool(),
//slow_job_pool: &client.state().slow_job_pool(),
background_threadpool: &client.background_threadpool(),
body: humanoid_body,
gamma: global_state.settings.graphics.gamma,
exposure: global_state.settings.graphics.exposure,

View File

@ -50,16 +50,17 @@ impl ClientInit {
username: String,
view_distance: Option<u32>,
password: String,
runtime: Option<Arc<runtime::Runtime>>,
// Threadpool resources shared with the singleplayer server
shared_resources: Option<(Arc<runtime::Runtime>, Arc<uvth::ThreadPool>)>,
) -> Self {
let (tx, rx) = unbounded();
let (trust_tx, trust_rx) = unbounded();
let cancel = Arc::new(AtomicBool::new(false));
let cancel2 = Arc::clone(&cancel);
let runtime = runtime.unwrap_or_else(|| {
let (runtime, background_threadpool) = shared_resources.unwrap_or_else(|| {
let cores = num_cpus::get();
Arc::new(
let runtime = Arc::new(
runtime::Builder::new_multi_thread()
.enable_all()
.worker_threads(if cores > 4 { cores - 1 } else { cores })
@ -70,7 +71,16 @@ impl ClientInit {
})
.build()
.unwrap(),
)
);
let threadpool = Arc::new(uvth::ThreadPoolBuilder::new()
.num_threads(cores.max(2) / 2 + cores / 4)
.name("background_threadpool".into())
.build());
(runtime, threadpool)
});
let runtime2 = Arc::clone(&runtime);
@ -106,6 +116,7 @@ impl ClientInit {
connection_args.clone(),
view_distance,
Arc::clone(&runtime2),
Arc::clone(&background_threadpool),
)
.await
{

View File

@ -69,7 +69,7 @@ impl PlayState for MainMenuState {
{
if let Some(singleplayer) = &global_state.singleplayer {
match singleplayer.receiver.try_recv() {
Ok(Ok(runtime)) => {
Ok(Ok(shared_resources)) => {
// Attempt login after the server is finished initializing
attempt_login(
&mut global_state.settings,
@ -78,7 +78,7 @@ impl PlayState for MainMenuState {
"".to_owned(),
ClientConnArgs::Resolved(ConnectionArgs::Mpsc(14004)),
&mut self.client_init,
Some(runtime),
Some(shared_resources),
);
},
Ok(Err(e)) => {
@ -339,7 +339,7 @@ fn attempt_login(
password: String,
connection_args: ClientConnArgs,
client_init: &mut Option<ClientInit>,
runtime: Option<Arc<runtime::Runtime>>,
shared_resources: Option<(Arc<runtime::Runtime>, Arc<uvth::ThreadPool>)>,
) {
if comp::Player::alias_is_valid(&username) {
// Don't try to connect if there is already a connection in progress.
@ -349,7 +349,7 @@ fn attempt_login(
username,
Some(settings.graphics.view_distance),
password,
runtime,
shared_resources,
));
}
} else {

View File

@ -21,7 +21,6 @@ use common::{
CharacterState,
},
figure::Segment,
slowjob::SlowJobPool,
vol::BaseVol,
};
use core::{hash::Hash, ops::Range};
@ -338,7 +337,8 @@ where
tick: u64,
camera_mode: CameraMode,
character_state: Option<&CharacterState>,
slow_jobs: &SlowJobPool,
//slow_jobs: &SlowJobPool,
background_threadpool: &uvth::ThreadPool,
) -> (FigureModelEntryLod<'c>, &'c Skel::Attr)
where
for<'a> &'a Skel::Body: Into<Skel::Attr>,
@ -404,7 +404,8 @@ where
let manifests = self.manifests;
let slot_ = Arc::clone(&slot);
slow_jobs.spawn("FIGURE_MESHING", move || {
//slow_jobs.spawn("FIGURE_MESHING", move || {
background_threadpool.execute(move || {
// First, load all the base vertex data.
let manifests = &*manifests.read();
let meshes = <Skel::Body as BodySpec>::bone_meshes(&key, manifests);

View File

@ -561,7 +561,8 @@ impl FigureMgr {
};
let camera_mode = camera.get_mode();
let character_state_storage = state.read_storage::<common::comp::CharacterState>();
let slow_jobs = state.slow_job_pool();
//let slow_jobs = state.slow_job_pool();
let background_threadpool = scene_data.background_threadpool;
let character_state = character_state_storage.get(scene_data.player_entity);
let focus_pos = anim::vek::Vec3::<f32>::from(camera.get_focus_pos());
@ -757,7 +758,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -1566,7 +1567,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -1768,7 +1769,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -2095,7 +2096,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -2454,7 +2455,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -2564,7 +2565,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -2653,7 +2654,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -3001,7 +3002,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state =
@ -3095,7 +3096,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -3282,7 +3283,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -3373,7 +3374,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -3462,7 +3463,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self
@ -3954,7 +3955,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state =
@ -4138,7 +4139,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state =
@ -4266,7 +4267,7 @@ impl FigureMgr {
tick,
player_camera_mode,
player_character_state,
&slow_jobs,
background_threadpool,
);
let state = self

View File

@ -109,6 +109,7 @@ pub struct Scene {
pub struct SceneData<'a> {
pub state: &'a State,
pub background_threadpool: &'a uvth::ThreadPool,
pub player_entity: specs::Entity,
pub target_entity: Option<specs::Entity>,
pub loaded_distance: f32,

View File

@ -26,7 +26,6 @@ use common::{
item::ItemKind,
},
figure::Segment,
slowjob::SlowJobPool,
terrain::BlockKind,
vol::{BaseVol, ReadVol},
};
@ -97,7 +96,8 @@ pub struct SceneData<'a> {
pub time: f64,
pub delta_time: f32,
pub tick: u64,
pub slow_job_pool: &'a SlowJobPool,
//pub slow_job_pool: &'a SlowJobPool,
pub background_threadpool: &'a uvth::ThreadPool,
pub body: Option<humanoid::Body>,
pub gamma: f32,
pub exposure: f32,
@ -357,7 +357,7 @@ impl Scene {
scene_data.tick,
CameraMode::default(),
None,
scene_data.slow_job_pool,
scene_data.background_threadpool,
)
.0;
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];

View File

@ -800,9 +800,9 @@ impl<V: RectRasterableVol> Terrain<V> {
let cnt = Arc::clone(&self.mesh_todos_active);
cnt.fetch_add(1, Ordering::Relaxed);
scene_data
.state
.slow_job_pool()
.spawn("TERRAIN_MESHING", move || {
.background_threadpool
//.spawn("TERRAIN_MESHING", move || {
.execute(move || {
let sprite_data = sprite_data;
let _ = send.send(mesh_worker(
pos,

View File

@ -1511,6 +1511,7 @@ impl PlayState for SessionState {
let client = self.client.borrow();
let scene_data = SceneData {
state: client.state(),
background_threadpool: &client.background_threadpool(),
player_entity: client.entity(),
// Only highlight if interactable
target_entity: self.interactable.and_then(Interactable::entity),
@ -1578,6 +1579,7 @@ impl PlayState for SessionState {
let scene_data = SceneData {
state: client.state(),
background_threadpool: &client.background_threadpool(),
player_entity: client.entity(),
// Only highlight if interactable
target_entity: self.interactable.and_then(Interactable::entity),

View File

@ -19,7 +19,7 @@ const TPS: u64 = 30;
pub struct Singleplayer {
_server_thread: JoinHandle<()>,
stop_server_s: Sender<()>,
pub receiver: Receiver<Result<Arc<Runtime>, ServerError>>,
pub receiver: Receiver<Result<(Arc<Runtime>, Arc<uvth::ThreadPool>), ServerError>>,
// Wether the server is stopped or not
paused: Arc<AtomicBool>,
// Settings that the server was started with
@ -93,6 +93,13 @@ impl Singleplayer {
.unwrap(),
);
let background_threadpool = Arc::new(
uvth::ThreadPoolBuilder::new()
.num_threads(cores.max(2) / 2 + cores / 4)
.name("background_threadpool".into())
.build(),
);
let settings2 = settings.clone();
let paused = Arc::new(AtomicBool::new(false));
@ -111,10 +118,11 @@ impl Singleplayer {
editable_settings,
&server_data_dir,
Arc::clone(&runtime),
Arc::clone(&background_threadpool),
) {
Ok(s) => {
server = Some(s);
Ok(runtime)
Ok((runtime, background_threadpool))
},
Err(e) => Err(e),
},