Skip to content

Commit 5bef04e

Browse files
committed
Rename things related to the main thread's operations.
It took me some time to understand how the main thread can lend a jobserver token to an LLVM thread. This commit renames a couple of things to make it clearer. - Rename the `LLVMing` variant as `Lending`, because that is a clearer description of what is happening. - Rename `running` as `running_with_own_token`, which makes it clearer that there might be one additional LLVM thread running (with a loaned token). Also add a comment to its definition.
1 parent fd017d3 commit 5bef04e

File tree

1 file changed

+46
-30
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+46
-30
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -998,9 +998,14 @@ struct Diagnostic {
998998

999999
#[derive(PartialEq, Clone, Copy, Debug)]
10001000
enum MainThreadWorkerState {
1001+
/// Doing nothing.
10011002
Idle,
1003+
1004+
/// Doing codegen, i.e. MIR-to-LLVM-IR conversion.
10021005
Codegenning,
1003-
LLVMing,
1006+
1007+
/// Idle, but lending the compiler process's Token to an LLVM thread so it can do useful work.
1008+
Lending,
10041009
}
10051010

10061011
fn start_executing_work<B: ExtraBackendMethods>(
@@ -1296,7 +1301,13 @@ fn start_executing_work<B: ExtraBackendMethods>(
12961301
let mut tokens = Vec::new();
12971302

12981303
let mut main_thread_worker_state = MainThreadWorkerState::Idle;
1299-
let mut running = 0;
1304+
1305+
// How many LLVM worker threads are running while holding a Token. This
1306+
// *excludes* the LLVM worker thread that the main thread is lending a
1307+
// Token to (when the main thread is in the `Lending` state).
1308+
// In other words, the number of LLVM threads is actually equal to
1309+
// `running + if main_thread_worker_state == Lending { 1 } else { 0 }`.
1310+
let mut running_with_own_token = 0;
13001311

13011312
let prof = &cgcx.prof;
13021313
let mut llvm_start_time: Option<VerboseTimingGuard<'_>> = None;
@@ -1307,8 +1318,8 @@ fn start_executing_work<B: ExtraBackendMethods>(
13071318
// only apply if codegen hasn't been aborted as they represent pending
13081319
// work to be done.
13091320
while codegen_state == Ongoing
1310-
|| running > 0
1311-
|| main_thread_worker_state == MainThreadWorkerState::LLVMing
1321+
|| running_with_own_token > 0
1322+
|| main_thread_worker_state == MainThreadWorkerState::Lending
13121323
|| (codegen_state == Completed
13131324
&& !(work_items.is_empty()
13141325
&& needs_fat_lto.is_empty()
@@ -1323,13 +1334,14 @@ fn start_executing_work<B: ExtraBackendMethods>(
13231334
if main_thread_worker_state == MainThreadWorkerState::Idle {
13241335
// Compute the number of workers that will be running once we've taken as many
13251336
// items from the work queue as we can, plus one for the main thread. It's not
1326-
// critically important that we use this instead of just `running`, but it
1327-
// prevents the `queue_full_enough` heuristic from fluctuating just because a
1328-
// worker finished up and we decreased the `running` count, even though we're
1329-
// just going to increase it right after this when we put a new worker to work.
1330-
let extra_tokens = tokens.len().checked_sub(running).unwrap();
1337+
// critically important that we use this instead of just
1338+
// `running_with_own_token`, but it prevents the `queue_full_enough` heuristic
1339+
// from fluctuating just because a worker finished up and we decreased the
1340+
// `running_with_own_token` count, even though we're just going to increase it
1341+
// right after this when we put a new worker to work.
1342+
let extra_tokens = tokens.len().checked_sub(running_with_own_token).unwrap();
13311343
let additional_running = std::cmp::min(extra_tokens, work_items.len());
1332-
let anticipated_running = running + additional_running + 1;
1344+
let anticipated_running = running_with_own_token + additional_running + 1;
13331345

13341346
if !queue_full_enough(work_items.len(), anticipated_running) {
13351347
// The queue is not full enough, process more codegen units:
@@ -1352,7 +1364,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
13521364
cgcx.config(item.module_kind()),
13531365
&mut llvm_start_time,
13541366
);
1355-
main_thread_worker_state = MainThreadWorkerState::LLVMing;
1367+
main_thread_worker_state = MainThreadWorkerState::Lending;
13561368
spawn_work(cgcx, item);
13571369
}
13581370
}
@@ -1363,7 +1375,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
13631375
// going to LTO and then push a bunch of work items onto our
13641376
// queue to do LTO
13651377
if work_items.is_empty()
1366-
&& running == 0
1378+
&& running_with_own_token == 0
13671379
&& main_thread_worker_state == MainThreadWorkerState::Idle
13681380
{
13691381
assert!(!started_lto);
@@ -1401,7 +1413,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
14011413
cgcx.config(item.module_kind()),
14021414
&mut llvm_start_time,
14031415
);
1404-
main_thread_worker_state = MainThreadWorkerState::LLVMing;
1416+
main_thread_worker_state = MainThreadWorkerState::Lending;
14051417
spawn_work(cgcx, item);
14061418
} else {
14071419
// There is no unstarted work, so let the main thread
@@ -1410,16 +1422,16 @@ fn start_executing_work<B: ExtraBackendMethods>(
14101422
// We reduce the `running` counter by one. The
14111423
// `tokens.truncate()` below will take care of
14121424
// giving the Token back.
1413-
debug_assert!(running > 0);
1414-
running -= 1;
1415-
main_thread_worker_state = MainThreadWorkerState::LLVMing;
1425+
debug_assert!(running_with_own_token > 0);
1426+
running_with_own_token -= 1;
1427+
main_thread_worker_state = MainThreadWorkerState::Lending;
14161428
}
14171429
}
14181430
MainThreadWorkerState::Codegenning => bug!(
14191431
"codegen worker should not be codegenning after \
14201432
codegen was already completed"
14211433
),
1422-
MainThreadWorkerState::LLVMing => {
1434+
MainThreadWorkerState::Lending => {
14231435
// Already making good use of that token
14241436
}
14251437
}
@@ -1431,7 +1443,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
14311443

14321444
// Spin up what work we can, only doing this while we've got available
14331445
// parallelism slots and work left to spawn.
1434-
while codegen_state != Aborted && !work_items.is_empty() && running < tokens.len() {
1446+
while codegen_state != Aborted
1447+
&& !work_items.is_empty()
1448+
&& running_with_own_token < tokens.len()
1449+
{
14351450
let (item, _) = work_items.pop().unwrap();
14361451

14371452
maybe_start_llvm_timer(prof, cgcx.config(item.module_kind()), &mut llvm_start_time);
@@ -1440,22 +1455,22 @@ fn start_executing_work<B: ExtraBackendMethods>(
14401455
CodegenContext { worker: get_worker_id(&mut free_worker_ids), ..cgcx.clone() };
14411456

14421457
spawn_work(cgcx, item);
1443-
running += 1;
1458+
running_with_own_token += 1;
14441459
}
14451460

1446-
// Relinquish accidentally acquired extra tokens
1447-
tokens.truncate(running);
1461+
// Relinquish accidentally acquired extra tokens.
1462+
tokens.truncate(running_with_own_token);
14481463

14491464
// If a thread exits successfully then we drop a token associated
1450-
// with that worker and update our `running` count. We may later
1451-
// re-acquire a token to continue running more work. We may also not
1452-
// actually drop a token here if the worker was running with an
1453-
// "ephemeral token"
1465+
// with that worker and update our `running_with_own_token` count.
1466+
// We may later re-acquire a token to continue running more work.
1467+
// We may also not actually drop a token here if the worker was
1468+
// running with an "ephemeral token".
14541469
let mut free_worker = |worker_id| {
1455-
if main_thread_worker_state == MainThreadWorkerState::LLVMing {
1470+
if main_thread_worker_state == MainThreadWorkerState::Lending {
14561471
main_thread_worker_state = MainThreadWorkerState::Idle;
14571472
} else {
1458-
running -= 1;
1473+
running_with_own_token -= 1;
14591474
}
14601475

14611476
free_worker_ids.push(worker_id);
@@ -1471,13 +1486,13 @@ fn start_executing_work<B: ExtraBackendMethods>(
14711486
Ok(token) => {
14721487
tokens.push(token);
14731488

1474-
if main_thread_worker_state == MainThreadWorkerState::LLVMing {
1489+
if main_thread_worker_state == MainThreadWorkerState::Lending {
14751490
// If the main thread token is used for LLVM work
14761491
// at the moment, we turn that thread into a regular
14771492
// LLVM worker thread, so the main thread is free
14781493
// to react to codegen demand.
14791494
main_thread_worker_state = MainThreadWorkerState::Idle;
1480-
running += 1;
1495+
running_with_own_token += 1;
14811496
}
14821497
}
14831498
Err(e) => {
@@ -1523,7 +1538,8 @@ fn start_executing_work<B: ExtraBackendMethods>(
15231538
// to exit as soon as possible, but we want to make sure all
15241539
// existing work has finished. Flag codegen as being done, and
15251540
// then conditions above will ensure no more work is spawned but
1526-
// we'll keep executing this loop until `running` hits 0.
1541+
// we'll keep executing this loop until `running_with_own_token`
1542+
// hits 0.
15271543
Message::CodegenAborted => {
15281544
codegen_state = Aborted;
15291545
}

0 commit comments

Comments
 (0)