MCPcopy Create free account
hub / github.com/XpuOS/xsched / SyncCmdWithLock

Method SyncCmdWithLock

preempt/src/xqueue/launch_worker.cpp:303–368  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

301}
302
303std::unique_lock<MutexLock> LaunchWorker::SyncCmdWithLock(std::unique_lock<utils::MutexLock> lock,
304 std::shared_ptr<HwCommand> hw_cmd)
305{
306 XASSERT(hw_cmd->Synchronizable(), "The HwCommand should be synchronizable");
307
308 while (true) {
309 // Wait if the worker is paused.
310 while (true) {
311 // Check if it is already completed.
312 // Here checking every loop is necessary because the lock could have been released
313 // in the last inner/outer loop and the HwCommand may have been set to
314 // kCommandStateCompleted by other threads.
315 // It will cause bugs if not checking in the outer loop when the app is syncing this
316 // HwCommand, and the XQueue is suspened in the lock-released period in the last
317 // outer loop, i.e., unlock(); cmd->sync(); lock();
318 // It will also cause bugs if not checking in the inner loop when:
319 // 1. the XQueue is suspended
320 // 2. this thread is waiting on cv_.wait(lock);
321 // 3. lock is released and the XQueue is resumed
322 // 4. hw_cmd is set to completed by another thread
323 // 5. the XQueue is again suspended
324 // 6. this thread wakes up and locks, finds the XQueue is suspended
325 if (hw_cmd->GetState() >= kCommandStateCompleted) return lock;
326
327 if (state_ == kWorkerStateRunning) {
328 break;
329 } else if (state_ == kWorkerStatePaused) {
330 cv_.wait(lock);
331 } else if (state_ == kWorkerStateTerminated) {
332 return lock;
333 } else {
334 XASSERT(false, "Invalid worker state");
335 }
336 }
337
338 XCommandState state = hw_cmd->GetState();
339 XASSERT(state >= kCommandStateInFlight, "The syncing HwCommand is not launched");
340 if (state == kCommandStateCompleted) break;
341
342 int64_t current_pause_cnt = pause_count_;
343
344 lock.unlock();
345 hw_cmd->Synchronize();
346 lock.lock();
347
348 // Check if preemption happened during hw_cmd->Synchronize().
349 if (current_pause_cnt == pause_count_) break;
350 }
351
352 // Pop and delete all HwCommands launched in previous.
353 const int64_t current_command_idx = hw_cmd->GetIdx();
354
355 while (sync_cmd_log_.size() > 0) {
356 if (sync_cmd_log_.front()->GetIdx() > current_command_idx) break;
357 sync_cmd_log_.pop_front();
358 }
359
360 while (cmd_log_.size() > 0) {

Callers

nothing calls this directly

Calls 7

GetStateMethod · 0.80
GetIdxMethod · 0.80
SetStateMethod · 0.80
SynchronizableMethod · 0.45
unlockMethod · 0.45
SynchronizeMethod · 0.45
lockMethod · 0.45

Tested by

no test coverage detected