Start starts execution of all tasks in k. Preconditions: Start may be called exactly once.
()
| 1412 | // |
| 1413 | // Preconditions: Start may be called exactly once. |
| 1414 | func (k *Kernel) Start() error { |
| 1415 | k.extMu.Lock() |
| 1416 | defer k.extMu.Unlock() |
| 1417 | |
| 1418 | if k.started { |
| 1419 | return fmt.Errorf("kernel already started") |
| 1420 | } |
| 1421 | |
| 1422 | k.started = true |
| 1423 | k.cpuClockTickTimer = time.NewTimer(linux.ClockTick) |
| 1424 | k.runningTasksMu.Lock() |
| 1425 | k.cpuClockTickerRunning = true |
| 1426 | k.runningTasksMu.Unlock() |
| 1427 | go k.runCPUClockTicker() |
| 1428 | // If k was created by LoadKernelFrom, timers were stopped during |
| 1429 | // Kernel.SaveTo and need to be resumed. If k was created by NewKernel, |
| 1430 | // this is a no-op. |
| 1431 | k.resumeTimeLocked(k.SupervisorContext()) |
| 1432 | k.tasks.mu.RLock() |
| 1433 | ts := make([]*Task, 0, len(k.tasks.Root.tids)) |
| 1434 | for t := range k.tasks.Root.tids { |
| 1435 | ts = append(ts, t) |
| 1436 | } |
| 1437 | k.tasks.mu.RUnlock() |
| 1438 | // Start task goroutines. |
| 1439 | // NOTE(b/235349091): We don't actually need the TaskSet mutex, we just |
| 1440 | // need to make sure we only call t.Start() once for each task. Holding the |
| 1441 | // mutex for each task start may cause a nested locking error. |
| 1442 | for _, t := range ts { |
| 1443 | t.Start(t.ThreadID()) |
| 1444 | } |
| 1445 | return nil |
| 1446 | } |
| 1447 | |
| 1448 | // pauseTimeLocked pauses all Timers and Timekeeper updates. |
| 1449 | // |
nothing calls this directly
no test coverage detected