kernel: Introduce Thread::time_lock and Team::time_lock
This commit is contained in:
parent
3519eb334a
commit
72addc62e0
|
@ -264,10 +264,11 @@ struct Team : TeamThreadIteratorEntry<team_id>, KernelReferenceable,
|
|||
|
||||
struct team_debug_info debug_info;
|
||||
|
||||
// protected by scheduler lock
|
||||
// protected by time_lock
|
||||
bigtime_t dead_threads_kernel_time;
|
||||
bigtime_t dead_threads_user_time;
|
||||
bigtime_t cpu_clock_offset;
|
||||
spinlock time_lock;
|
||||
|
||||
// user group information; protected by fLock, the *_uid/*_gid fields also
|
||||
// by the scheduler lock
|
||||
|
@ -516,7 +517,7 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, KernelReferenceable,
|
|||
bigtime_t user_time; // protected by time_lock
|
||||
bigtime_t kernel_time; // protected by time_lock
|
||||
bigtime_t last_time; // protected by time_lock
|
||||
bigtime_t cpu_clock_offset; // protected by scheduler lock
|
||||
bigtime_t cpu_clock_offset; // protected by time_lock
|
||||
|
||||
void (*post_interrupt_callback)(void*);
|
||||
void* post_interrupt_data;
|
||||
|
@ -610,7 +611,7 @@ private:
|
|||
|
||||
UserTimerList fUserTimers; // protected by fLock
|
||||
ThreadTimeUserTimerList fCPUTimeUserTimers;
|
||||
// protected by scheduler lock
|
||||
// protected by time_lock
|
||||
};
|
||||
|
||||
|
||||
|
@ -749,7 +750,7 @@ Thread::DequeuePendingSignal(sigset_t nonBlocked, Signal& buffer)
|
|||
|
||||
/*! Returns the thread's current total CPU time (kernel + user + offset).
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
The caller must hold \c time_lock.
|
||||
|
||||
\param ignoreCurrentRun If \c true and the thread is currently running,
|
||||
don't add the time since the last time \c last_time was updated. Should
|
||||
|
@ -764,7 +765,7 @@ Thread::CPUTime(bool ignoreCurrentRun) const
|
|||
|
||||
// If currently running, also add the time since the last check, unless
|
||||
// requested otherwise.
|
||||
if (!ignoreCurrentRun && cpu != NULL)
|
||||
if (!ignoreCurrentRun && last_time != 0)
|
||||
time += system_time() - last_time;
|
||||
|
||||
return time;
|
||||
|
|
|
@ -137,8 +137,6 @@ UserTimer::~UserTimer()
|
|||
Cancels the timer, if it is already scheduled, and optionally schedules it
|
||||
with new parameters.
|
||||
|
||||
The caller must not hold the scheduler lock.
|
||||
|
||||
\param nextTime The time at which the timer should go off the next time. If
|
||||
\c B_INFINITE_TIMEOUT, the timer will not be scheduled. Whether the
|
||||
value is interpreted as absolute or relative time, depends on \c flags.
|
||||
|
@ -160,8 +158,6 @@ UserTimer::~UserTimer()
|
|||
|
||||
|
||||
/*! Cancels the timer, if it is scheduled.
|
||||
|
||||
The caller must not hold the scheduler lock.
|
||||
*/
|
||||
void
|
||||
UserTimer::Cancel()
|
||||
|
@ -176,8 +172,6 @@ UserTimer::Cancel()
|
|||
uint32& _overrunCount)
|
||||
Return information on the current timer.
|
||||
|
||||
The caller must not hold the scheduler lock.
|
||||
|
||||
\param _remainingTime Return variable that will be set to the microseconds
|
||||
remaining to the time for which the timer was scheduled next before the
|
||||
call. If it wasn't scheduled, the variable is set to
|
||||
|
@ -513,7 +507,7 @@ TeamTimeUserTimer::Schedule(bigtime_t nextTime, bigtime_t interval,
|
|||
uint32 flags, bigtime_t& _oldRemainingTime, bigtime_t& _oldInterval)
|
||||
{
|
||||
InterruptsWriteSequentialLocker locker(sUserTimerLock);
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
SpinLocker timeLocker(fTeam != NULL ? &fTeam->time_lock : NULL);
|
||||
|
||||
// get the current time, but only if needed
|
||||
bool nowValid = fTeam != NULL;
|
||||
|
@ -547,9 +541,13 @@ TeamTimeUserTimer::Schedule(bigtime_t nextTime, bigtime_t interval,
|
|||
|
||||
// Get the team. If it doesn't exist anymore, just don't schedule the
|
||||
// timer anymore.
|
||||
fTeam = Team::Get(fTeamID);
|
||||
if (fTeam == NULL)
|
||||
Team* newTeam = Team::Get(fTeamID);
|
||||
if (newTeam == NULL) {
|
||||
fTeam = NULL;
|
||||
return;
|
||||
} else if (fTeam == NULL)
|
||||
timeLocker.SetTo(newTeam->time_lock, false);
|
||||
fTeam = newTeam;
|
||||
|
||||
fAbsolute = (flags & B_RELATIVE_TIMEOUT) == 0;
|
||||
|
||||
|
@ -576,7 +574,7 @@ TeamTimeUserTimer::GetInfo(bigtime_t& _remainingTime, bigtime_t& _interval,
|
|||
count = acquire_read_seqlock(&sUserTimerLock);
|
||||
|
||||
if (fTeam != NULL) {
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(fTeam->time_lock);
|
||||
_remainingTime = fNextTime - fTeam->CPUTime(false);
|
||||
_interval = fInterval;
|
||||
} else {
|
||||
|
@ -591,7 +589,7 @@ TeamTimeUserTimer::GetInfo(bigtime_t& _remainingTime, bigtime_t& _interval,
|
|||
|
||||
/*! Deactivates the timer, if it is activated.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
*/
|
||||
void
|
||||
TeamTimeUserTimer::Deactivate()
|
||||
|
@ -619,7 +617,7 @@ TeamTimeUserTimer::Deactivate()
|
|||
was just set. Schedules a kernel timer for the remaining time, respectively
|
||||
cancels it.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
|
||||
\param unscheduledThread If not \c NULL, this is the thread that is
|
||||
currently running and which is in the process of being unscheduled.
|
||||
|
@ -646,7 +644,7 @@ TeamTimeUserTimer::Update(Thread* unscheduledThread)
|
|||
/*! Called when the team's CPU time clock which this timer refers to has been
|
||||
set.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
|
||||
\param changedBy The value by which the clock has changed.
|
||||
*/
|
||||
|
@ -689,7 +687,7 @@ TeamTimeUserTimer::HandleTimer()
|
|||
/*! Schedules/cancels the kernel timer as necessary.
|
||||
|
||||
\c fRunningThreads must be up-to-date.
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
|
||||
\param unscheduling \c true, when the current thread is in the process of
|
||||
being unscheduled.
|
||||
|
@ -757,7 +755,7 @@ TeamUserTimeUserTimer::Schedule(bigtime_t nextTime, bigtime_t interval,
|
|||
uint32 flags, bigtime_t& _oldRemainingTime, bigtime_t& _oldInterval)
|
||||
{
|
||||
InterruptsWriteSequentialLocker locker(sUserTimerLock);
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
SpinLocker timeLocker(fTeam != NULL ? &fTeam->time_lock : NULL);
|
||||
|
||||
// get the current time, but only if needed
|
||||
bool nowValid = fTeam != NULL;
|
||||
|
@ -786,9 +784,13 @@ TeamUserTimeUserTimer::Schedule(bigtime_t nextTime, bigtime_t interval,
|
|||
|
||||
// Get the team. If it doesn't exist anymore, just don't schedule the
|
||||
// timer anymore.
|
||||
fTeam = Team::Get(fTeamID);
|
||||
if (fTeam == NULL)
|
||||
Team* newTeam = Team::Get(fTeamID);
|
||||
if (newTeam == NULL) {
|
||||
fTeam = NULL;
|
||||
return;
|
||||
} else if (fTeam == NULL)
|
||||
timeLocker.SetTo(newTeam->time_lock, false);
|
||||
fTeam = newTeam;
|
||||
|
||||
// convert relative to absolute timeouts
|
||||
if ((flags & B_RELATIVE_TIMEOUT) != 0) {
|
||||
|
@ -813,7 +815,7 @@ TeamUserTimeUserTimer::GetInfo(bigtime_t& _remainingTime, bigtime_t& _interval,
|
|||
count = acquire_read_seqlock(&sUserTimerLock);
|
||||
|
||||
if (fTeam != NULL) {
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(fTeam->time_lock);
|
||||
_remainingTime = fNextTime - fTeam->UserCPUTime();
|
||||
_interval = fInterval;
|
||||
} else {
|
||||
|
@ -828,7 +830,7 @@ TeamUserTimeUserTimer::GetInfo(bigtime_t& _remainingTime, bigtime_t& _interval,
|
|||
|
||||
/*! Deactivates the timer, if it is activated.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
*/
|
||||
void
|
||||
TeamUserTimeUserTimer::Deactivate()
|
||||
|
@ -845,7 +847,7 @@ TeamUserTimeUserTimer::Deactivate()
|
|||
|
||||
/*! Checks whether the timer is up, firing an event, if so.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
*/
|
||||
void
|
||||
TeamUserTimeUserTimer::Check()
|
||||
|
@ -899,7 +901,7 @@ ThreadTimeUserTimer::Schedule(bigtime_t nextTime, bigtime_t interval,
|
|||
uint32 flags, bigtime_t& _oldRemainingTime, bigtime_t& _oldInterval)
|
||||
{
|
||||
InterruptsWriteSequentialLocker locker(sUserTimerLock);
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
SpinLocker timeLocker(fThread->time_lock);
|
||||
|
||||
// get the current time, but only if needed
|
||||
bool nowValid = fThread != NULL;
|
||||
|
@ -933,9 +935,13 @@ ThreadTimeUserTimer::Schedule(bigtime_t nextTime, bigtime_t interval,
|
|||
|
||||
// Get the thread. If it doesn't exist anymore, just don't schedule the
|
||||
// timer anymore.
|
||||
fThread = Thread::Get(fThreadID);
|
||||
if (fThread == NULL)
|
||||
Thread* newThread = Thread::Get(fThreadID);
|
||||
if (newThread == NULL) {
|
||||
fThread = NULL;
|
||||
return;
|
||||
} else if (fThread == NULL)
|
||||
timeLocker.SetTo(newThread->time_lock, false);
|
||||
fThread = newThread;
|
||||
|
||||
fAbsolute = (flags & B_RELATIVE_TIMEOUT) == 0;
|
||||
|
||||
|
@ -963,7 +969,7 @@ ThreadTimeUserTimer::GetInfo(bigtime_t& _remainingTime, bigtime_t& _interval,
|
|||
count = acquire_read_seqlock(&sUserTimerLock);
|
||||
|
||||
if (fThread != NULL) {
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
SpinLocker timeLocker(fThread->time_lock);
|
||||
_remainingTime = fNextTime - fThread->CPUTime(false);
|
||||
_interval = fInterval;
|
||||
} else {
|
||||
|
@ -978,7 +984,7 @@ ThreadTimeUserTimer::GetInfo(bigtime_t& _remainingTime, bigtime_t& _interval,
|
|||
|
||||
/*! Deactivates the timer, if it is activated.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
*/
|
||||
void
|
||||
ThreadTimeUserTimer::Deactivate()
|
||||
|
@ -1005,7 +1011,7 @@ ThreadTimeUserTimer::Deactivate()
|
|||
scheduled, or, when the timer was just set and the thread is already
|
||||
running. Schedules a kernel timer for the remaining time.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
*/
|
||||
void
|
||||
ThreadTimeUserTimer::Start()
|
||||
|
@ -1066,7 +1072,7 @@ ThreadTimeUserTimer::Stop()
|
|||
/*! Called when the team's CPU time clock which this timer refers to has been
|
||||
set.
|
||||
|
||||
The caller must hold the scheduler lock and \c sUserTimerLock.
|
||||
The caller must hold \c time_lock and \c sUserTimerLock.
|
||||
|
||||
\param changedBy The value by which the clock has changed.
|
||||
*/
|
||||
|
@ -1358,7 +1364,7 @@ create_timer(clockid_t clockID, int32 timerID, Team* team, Thread* thread,
|
|||
|
||||
/*! Called when the CPU time clock of the given thread has been set.
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
The caller must hold \c time_lock.
|
||||
|
||||
\param thread The thread whose CPU time clock has been set.
|
||||
\param changedBy The value by which the CPU time clock has changed
|
||||
|
@ -1377,7 +1383,7 @@ thread_clock_changed(Thread* thread, bigtime_t changedBy)
|
|||
|
||||
/*! Called when the CPU time clock of the given team has been set.
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
The caller must hold \c time_lock.
|
||||
|
||||
\param team The team whose CPU time clock has been set.
|
||||
\param changedBy The value by which the CPU time clock has changed
|
||||
|
@ -1477,7 +1483,7 @@ user_timer_get_clock(clockid_t clockID, bigtime_t& _time)
|
|||
case CLOCK_THREAD_CPUTIME_ID:
|
||||
{
|
||||
Thread* thread = thread_get_current_thread();
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(thread->time_lock);
|
||||
_time = thread->CPUTime(false);
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1485,7 +1491,7 @@ user_timer_get_clock(clockid_t clockID, bigtime_t& _time)
|
|||
case CLOCK_PROCESS_USER_CPUTIME_ID:
|
||||
{
|
||||
Team* team = thread_get_current_thread()->team;
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(team->time_lock);
|
||||
_time = team->UserCPUTime();
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1513,7 +1519,7 @@ user_timer_get_clock(clockid_t clockID, bigtime_t& _time)
|
|||
BReference<Team> teamReference(team, true);
|
||||
|
||||
// get the time
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(team->time_lock);
|
||||
_time = team->CPUTime(false);
|
||||
|
||||
return B_OK;
|
||||
|
@ -1630,7 +1636,7 @@ _user_set_clock(clockid_t clockID, bigtime_t time)
|
|||
case CLOCK_THREAD_CPUTIME_ID:
|
||||
{
|
||||
Thread* thread = thread_get_current_thread();
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(thread->time_lock);
|
||||
bigtime_t diff = time - thread->CPUTime(false);
|
||||
thread->cpu_clock_offset += diff;
|
||||
|
||||
|
@ -1665,7 +1671,7 @@ _user_set_clock(clockid_t clockID, bigtime_t time)
|
|||
BReference<Team> teamReference(team, true);
|
||||
|
||||
// set the time offset
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(team->time_lock);
|
||||
bigtime_t diff = time - team->CPUTime(false);
|
||||
team->cpu_clock_offset += diff;
|
||||
|
||||
|
|
|
@ -26,10 +26,14 @@ scheduler_switch_thread(Thread* fromThread, Thread* toThread)
|
|||
user_debug_thread_unscheduled(fromThread);
|
||||
|
||||
// stop CPU time based user timers
|
||||
acquire_spinlock(&fromThread->team->time_lock);
|
||||
acquire_spinlock(&fromThread->time_lock);
|
||||
if (fromThread->HasActiveCPUTimeUserTimers()
|
||||
|| fromThread->team->HasActiveCPUTimeUserTimers()) {
|
||||
user_timer_stop_cpu_timers(fromThread, toThread);
|
||||
}
|
||||
release_spinlock(&fromThread->time_lock);
|
||||
release_spinlock(&fromThread->team->time_lock);
|
||||
|
||||
// update CPU and Thread structures and perform the context switch
|
||||
cpu_ent* cpu = fromThread->cpu;
|
||||
|
@ -46,10 +50,14 @@ scheduler_switch_thread(Thread* fromThread, Thread* toThread)
|
|||
// first time the same is done in thread.cpp:common_thread_entry().
|
||||
|
||||
// continue CPU time based user timers
|
||||
acquire_spinlock(&fromThread->team->time_lock);
|
||||
acquire_spinlock(&fromThread->time_lock);
|
||||
if (fromThread->HasActiveCPUTimeUserTimers()
|
||||
|| fromThread->team->HasActiveCPUTimeUserTimers()) {
|
||||
user_timer_continue_cpu_timers(fromThread, cpu->previous_thread);
|
||||
}
|
||||
release_spinlock(&fromThread->time_lock);
|
||||
release_spinlock(&fromThread->team->time_lock);
|
||||
|
||||
// notify the user debugger code
|
||||
if ((fromThread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0)
|
||||
|
@ -69,6 +77,7 @@ scheduler_update_thread_times(Thread* oldThread, Thread* nextThread)
|
|||
} else {
|
||||
acquire_spinlock(&oldThread->time_lock);
|
||||
oldThread->kernel_time += now - oldThread->last_time;
|
||||
oldThread->last_time = 0;
|
||||
release_spinlock(&oldThread->time_lock);
|
||||
|
||||
acquire_spinlock(&nextThread->time_lock);
|
||||
|
@ -78,8 +87,11 @@ scheduler_update_thread_times(Thread* oldThread, Thread* nextThread)
|
|||
|
||||
// If the old thread's team has user time timers, check them now.
|
||||
Team* team = oldThread->team;
|
||||
|
||||
acquire_spinlock(&team->time_lock);
|
||||
if (team->HasActiveUserTimeUserTimers())
|
||||
user_timer_check_team_user_timers(team);
|
||||
release_spinlock(&team->time_lock);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -490,6 +490,7 @@ Team::Team(team_id id, bool kernel)
|
|||
// init dead/stopped/continued children condition vars
|
||||
dead_children.condition_variable.Init(&dead_children, "team children");
|
||||
|
||||
B_INITIALIZE_SPINLOCK(&time_lock);
|
||||
B_INITIALIZE_SPINLOCK(&signal_lock);
|
||||
|
||||
fQueuedSignalsCounter = new(std::nothrow) BKernel::QueuedSignalsCounter(
|
||||
|
@ -908,7 +909,7 @@ Team::DeactivateCPUTimeUserTimers()
|
|||
|
||||
/*! Returns the team's current total CPU time (kernel + user + offset).
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
The caller must hold \c time_lock.
|
||||
|
||||
\param ignoreCurrentRun If \c true and the current thread is one team's
|
||||
threads, don't add the time since the last time \c last_time was
|
||||
|
@ -931,7 +932,7 @@ Team::CPUTime(bool ignoreCurrentRun) const
|
|||
SpinLocker threadTimeLocker(thread->time_lock);
|
||||
time += thread->kernel_time + thread->user_time;
|
||||
|
||||
if (thread->IsRunning()) {
|
||||
if (thread->last_time != 0) {
|
||||
if (!ignoreCurrentRun || thread != currentThread)
|
||||
time += now - thread->last_time;
|
||||
}
|
||||
|
@ -943,7 +944,7 @@ Team::CPUTime(bool ignoreCurrentRun) const
|
|||
|
||||
/*! Returns the team's current user CPU time.
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
The caller must hold \c time_lock.
|
||||
|
||||
\return The team's current user CPU time.
|
||||
*/
|
||||
|
@ -959,7 +960,7 @@ Team::UserCPUTime() const
|
|||
SpinLocker threadTimeLocker(thread->time_lock);
|
||||
time += thread->user_time;
|
||||
|
||||
if (thread->IsRunning() && !thread->in_kernel)
|
||||
if (thread->last_time != 0 && !thread->in_kernel)
|
||||
time += now - thread->last_time;
|
||||
}
|
||||
|
||||
|
@ -3093,12 +3094,12 @@ team_shutdown_team(Team* team)
|
|||
team->DeleteUserTimers(false);
|
||||
|
||||
// deactivate CPU time user timers for the team
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
InterruptsSpinLocker timeLocker(team->time_lock);
|
||||
|
||||
if (team->HasActiveCPUTimeUserTimers())
|
||||
team->DeactivateCPUTimeUserTimers();
|
||||
|
||||
schedulerLocker.Unlock();
|
||||
timeLocker.Unlock();
|
||||
|
||||
// kill all threads but the main thread
|
||||
team_death_entry deathEntry;
|
||||
|
|
|
@ -696,18 +696,22 @@ common_thread_entry(void* _args)
|
|||
// The thread is new and has been scheduled the first time.
|
||||
|
||||
// start CPU time based user timers
|
||||
acquire_spinlock(&thread->team->time_lock);
|
||||
acquire_spinlock(&thread->time_lock);
|
||||
if (thread->HasActiveCPUTimeUserTimers()
|
||||
|| thread->team->HasActiveCPUTimeUserTimers()) {
|
||||
user_timer_continue_cpu_timers(thread, thread->cpu->previous_thread);
|
||||
}
|
||||
|
||||
// start tracking time
|
||||
thread->last_time = system_time();
|
||||
release_spinlock(&thread->time_lock);
|
||||
release_spinlock(&thread->team->time_lock);
|
||||
|
||||
// notify the user debugger code
|
||||
if ((thread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0)
|
||||
user_debug_thread_scheduled(thread);
|
||||
|
||||
// start tracking time
|
||||
thread->last_time = system_time();
|
||||
|
||||
// unlock the scheduler lock and enable interrupts
|
||||
release_spinlock(&gSchedulerLock);
|
||||
enable_interrupts();
|
||||
|
@ -1991,10 +1995,10 @@ thread_exit(void)
|
|||
|
||||
// remember how long this thread lasted
|
||||
bigtime_t now = system_time();
|
||||
InterruptsSpinLocker threadTimeLocker(thread->time_lock);
|
||||
InterruptsSpinLocker teamTimeLocker(team->time_lock);
|
||||
SpinLocker threadTimeLocker(thread->time_lock);
|
||||
thread->kernel_time += now - thread->last_time;
|
||||
thread->last_time = now;
|
||||
threadTimeLocker.Unlock();
|
||||
|
||||
team->dead_threads_kernel_time += thread->kernel_time;
|
||||
team->dead_threads_user_time += thread->user_time;
|
||||
|
@ -2009,6 +2013,9 @@ thread_exit(void)
|
|||
if (thread->HasActiveCPUTimeUserTimers())
|
||||
thread->DeactivateCPUTimeUserTimers();
|
||||
|
||||
threadTimeLocker.Unlock();
|
||||
teamTimeLocker.Unlock();
|
||||
|
||||
// put the thread into the kernel team until it dies
|
||||
remove_thread_from_team(team, thread);
|
||||
insert_thread_into_team(kernelTeam, thread);
|
||||
|
@ -2334,11 +2341,10 @@ thread_reset_for_exec(void)
|
|||
thread->user_stack_size = 0;
|
||||
|
||||
// reset signals
|
||||
InterruptsSpinLocker schedulerLocker(gSchedulerLock);
|
||||
|
||||
thread->ResetSignalsOnExec();
|
||||
|
||||
// reset thread CPU time clock
|
||||
InterruptsSpinLocker timeLocker(thread->time_lock);
|
||||
thread->cpu_clock_offset = -thread->CPUTime(false);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue