mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Refactor lock related code
This commit is contained in:
parent
c76eb67883
commit
fd292305f6
@ -96,8 +96,7 @@ size_t GetLocksCount() { return LocksCount.load(); }
|
|||||||
|
|
||||||
void LockClass::Yield()
|
void LockClass::Yield()
|
||||||
{
|
{
|
||||||
if (CPU::Interrupts(CPU::Check) &&
|
if (CPU::Interrupts(CPU::Check) && TaskManager &&
|
||||||
TaskManager &&
|
|
||||||
!TaskManager->IsPanic())
|
!TaskManager->IsPanic())
|
||||||
{
|
{
|
||||||
TaskManager->Yield();
|
TaskManager->Yield();
|
||||||
@ -123,10 +122,8 @@ void LockClass::DeadLock(SpinLockData &Lock)
|
|||||||
CCore = CoreData->ID;
|
CCore = CoreData->ID;
|
||||||
|
|
||||||
warn("Potential deadlock in lock '%s' held by '%s'! %ld %s in queue. Interrupts are %s. Core %ld held by %ld. (%ld times happened)",
|
warn("Potential deadlock in lock '%s' held by '%s'! %ld %s in queue. Interrupts are %s. Core %ld held by %ld. (%ld times happened)",
|
||||||
Lock.AttemptingToGet, Lock.CurrentHolder,
|
Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count, Lock.Count > 1 ? "locks" : "lock",
|
||||||
Lock.Count, Lock.Count > 1 ? "locks" : "lock",
|
CPU::Interrupts(CPU::Check) ? "enabled" : "disabled", CCore, Lock.Core, this->DeadLocks);
|
||||||
CPU::Interrupts(CPU::Check) ? "enabled" : "disabled",
|
|
||||||
CCore, Lock.Core, this->DeadLocks);
|
|
||||||
|
|
||||||
#ifdef PRINT_BACKTRACE
|
#ifdef PRINT_BACKTRACE
|
||||||
PrintStacktrace(&Lock);
|
PrintStacktrace(&Lock);
|
||||||
@ -201,10 +198,8 @@ void LockClass::TimeoutDeadLock(SpinLockData &Lock, uint64_t Timeout)
|
|||||||
uint64_t Counter = TimeManager->GetCounter();
|
uint64_t Counter = TimeManager->GetCounter();
|
||||||
|
|
||||||
warn("Potential deadlock in lock '%s' held by '%s'! %ld %s in queue. Interrupts are %s. Core %ld held by %ld. Timeout in %ld (%ld ticks remaining).",
|
warn("Potential deadlock in lock '%s' held by '%s'! %ld %s in queue. Interrupts are %s. Core %ld held by %ld. Timeout in %ld (%ld ticks remaining).",
|
||||||
Lock.AttemptingToGet, Lock.CurrentHolder,
|
Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count, Lock.Count > 1 ? "locks" : "lock",
|
||||||
Lock.Count, Lock.Count > 1 ? "locks" : "lock",
|
CPU::Interrupts(CPU::Check) ? "enabled" : "disabled", CCore, Lock.Core, Timeout, Timeout - Counter);
|
||||||
CPU::Interrupts(CPU::Check) ? "enabled" : "disabled",
|
|
||||||
CCore, Lock.Core, Timeout, Timeout - Counter);
|
|
||||||
|
|
||||||
#ifdef PRINT_BACKTRACE
|
#ifdef PRINT_BACKTRACE
|
||||||
PrintStacktrace(&Lock);
|
PrintStacktrace(&Lock);
|
||||||
|
@ -68,6 +68,32 @@ public:
|
|||||||
int TimeoutLock(const char *FunctionName, uint64_t Timeout);
|
int TimeoutLock(const char *FunctionName, uint64_t Timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class spin_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
LockClass lc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool locked()
|
||||||
|
{
|
||||||
|
return this->lc.Locked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lock(const char *FunctionName)
|
||||||
|
{
|
||||||
|
return this->lc.Lock(FunctionName) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unlock()
|
||||||
|
{
|
||||||
|
return this->lc.Unlock() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock() = default;
|
||||||
|
spin_lock(const spin_lock &) = delete;
|
||||||
|
~spin_lock() = default;
|
||||||
|
};
|
||||||
|
|
||||||
/** @brief Please use this macro to create a new smart lock. */
|
/** @brief Please use this macro to create a new smart lock. */
|
||||||
class SmartLockClass
|
class SmartLockClass
|
||||||
{
|
{
|
||||||
@ -106,6 +132,7 @@ public:
|
|||||||
this->LockPointer = &Lock;
|
this->LockPointer = &Lock;
|
||||||
this->LockPointer->TimeoutLock(FunctionName, Timeout);
|
this->LockPointer->TimeoutLock(FunctionName, Timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SmartTimeoutLockClass()
|
~SmartTimeoutLockClass()
|
||||||
{
|
{
|
||||||
this->LockPointer->Unlock();
|
this->LockPointer->Unlock();
|
||||||
@ -128,6 +155,7 @@ public:
|
|||||||
this->LockPointer = &Lock;
|
this->LockPointer = &Lock;
|
||||||
this->LockPointer->Lock(FunctionName);
|
this->LockPointer->Lock(FunctionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SmartLockCriticalSectionClass()
|
~SmartLockCriticalSectionClass()
|
||||||
{
|
{
|
||||||
this->LockPointer->Unlock();
|
this->LockPointer->Unlock();
|
||||||
@ -153,6 +181,7 @@ public:
|
|||||||
InterruptsEnabled = true;
|
InterruptsEnabled = true;
|
||||||
CPU::Interrupts(CPU::Disable);
|
CPU::Interrupts(CPU::Disable);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SmartCriticalSectionClass()
|
~SmartCriticalSectionClass()
|
||||||
{
|
{
|
||||||
if (InterruptsEnabled)
|
if (InterruptsEnabled)
|
||||||
|
@ -25,6 +25,21 @@
|
|||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct defer_lock_t
|
||||||
|
{
|
||||||
|
explicit defer_lock_t() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct try_to_lock_t
|
||||||
|
{
|
||||||
|
explicit try_to_lock_t() = default;
|
||||||
|
};
|
||||||
|
struct adopt_lock_t
|
||||||
|
{
|
||||||
|
explicit adopt_lock_t() = default;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mutex implementation.
|
* A mutex implementation.
|
||||||
*
|
*
|
||||||
@ -35,7 +50,7 @@ namespace std
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
atomic_bool Locked = false;
|
atomic_bool Locked = false;
|
||||||
vector<Tasking::TCB *> Waiting;
|
list<Tasking::TCB *> Waiting;
|
||||||
Tasking::TCB *Holder = nullptr;
|
Tasking::TCB *Holder = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -43,24 +58,37 @@ namespace std
|
|||||||
bool try_lock();
|
bool try_lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|
||||||
mutex() = default;
|
mutex();
|
||||||
mutex(const mutex &) = delete;
|
mutex(const mutex &) = delete;
|
||||||
~mutex() = default;
|
~mutex();
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Mutex>
|
template <class Mutex>
|
||||||
class lock_guard
|
class lock_guard
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Mutex &m;
|
Mutex &mutexRef;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit lock_guard(Mutex &mutex)
|
explicit lock_guard(Mutex &m)
|
||||||
: m(mutex) { m.lock(); }
|
: mutexRef(m)
|
||||||
|
{
|
||||||
|
mutexRef.lock();
|
||||||
|
}
|
||||||
|
|
||||||
~lock_guard() { m.unlock(); }
|
lock_guard(Mutex &m, adopt_lock_t t)
|
||||||
|
: mutexRef(m)
|
||||||
|
{
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
lock_guard(const lock_guard &) = delete;
|
lock_guard(const lock_guard &) = delete;
|
||||||
|
|
||||||
|
~lock_guard()
|
||||||
|
{
|
||||||
|
mutexRef.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
lock_guard &operator=(const lock_guard &) = delete;
|
lock_guard &operator=(const lock_guard &) = delete;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -29,53 +29,80 @@ namespace std
|
|||||||
{
|
{
|
||||||
void mutex::lock()
|
void mutex::lock()
|
||||||
{
|
{
|
||||||
|
RetryLock:
|
||||||
bool Result = this->Locked.exchange(true, std::memory_order_acquire);
|
bool Result = this->Locked.exchange(true, std::memory_order_acquire);
|
||||||
__sync;
|
|
||||||
|
|
||||||
if (Result)
|
TCB *tcb = thisThread;
|
||||||
|
if (Result == true)
|
||||||
{
|
{
|
||||||
this->Waiting.push_back(thisThread);
|
debug("%#lx: Mutex is locked, blocking task %d (\"%s\" : %d)", this,
|
||||||
thisThread->Block();
|
tcb->ID, tcb->Parent->Name, tcb->Parent->ID);
|
||||||
|
|
||||||
|
this->Waiting.push_back(tcb);
|
||||||
|
tcb->Block();
|
||||||
TaskManager->Yield();
|
TaskManager->Yield();
|
||||||
return;
|
goto RetryLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->Holder = thisThread;
|
this->Holder = tcb;
|
||||||
this->Waiting.erase(std::find(this->Waiting.begin(),
|
this->Waiting.remove(tcb);
|
||||||
this->Waiting.end(),
|
|
||||||
thisThread));
|
debug("%#lx: Mutex locked by task %d (\"%s\" : %d)", this,
|
||||||
|
tcb->ID, tcb->Parent->Name, tcb->Parent->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mutex::try_lock()
|
bool mutex::try_lock()
|
||||||
{
|
{
|
||||||
bool Result = this->Locked.exchange(true, std::memory_order_acquire);
|
bool Result = this->Locked.exchange(true, std::memory_order_acquire);
|
||||||
__sync;
|
|
||||||
|
|
||||||
if (!Result)
|
TCB *tcb = thisThread;
|
||||||
|
if (Result == true)
|
||||||
{
|
{
|
||||||
this->Holder = thisThread;
|
debug("%#lx: Mutex is locked, task %d (\"%s\" : %d) failed to lock", this,
|
||||||
this->Waiting.erase(std::find(this->Waiting.begin(),
|
tcb->ID, tcb->Parent->Name, tcb->Parent->ID);
|
||||||
this->Waiting.end(),
|
return false;
|
||||||
thisThread));
|
|
||||||
}
|
}
|
||||||
return !Result;
|
|
||||||
|
this->Holder = tcb;
|
||||||
|
this->Waiting.remove(tcb);
|
||||||
|
|
||||||
|
debug("%#lx: Mutex locked by task %d (\"%s\" : %d)", this,
|
||||||
|
tcb->ID, tcb->Parent->Name, tcb->Parent->ID);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutex::unlock()
|
void mutex::unlock()
|
||||||
{
|
{
|
||||||
__sync;
|
TCB *tcb = thisThread;
|
||||||
|
assert(this->Holder == tcb);
|
||||||
|
|
||||||
|
this->Holder = nullptr;
|
||||||
this->Locked.store(false, std::memory_order_release);
|
this->Locked.store(false, std::memory_order_release);
|
||||||
|
|
||||||
if (!this->Waiting.empty())
|
if (this->Waiting.empty())
|
||||||
{
|
{
|
||||||
this->Holder = this->Waiting[0];
|
debug("%#lx: Mutex unlocked, no tasks to unblock", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this->Holder = this->Waiting.front();
|
TCB *Next = this->Waiting.front();
|
||||||
this->Waiting.erase(this->Waiting.begin());
|
this->Waiting.pop_front();
|
||||||
this->Holder->Unblock();
|
|
||||||
TaskManager->Yield();
|
debug("%#lx: Mutex unlocked, task %d (\"%s\" : %d) unblocked", this,
|
||||||
|
Next->ID, Next->Parent->Name, Next->Parent->ID);
|
||||||
|
|
||||||
|
Next->Unblock();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
this->Holder = nullptr;
|
mutex::mutex()
|
||||||
|
{
|
||||||
|
debug("%#lx: Creating mutex", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex::~mutex()
|
||||||
|
{
|
||||||
|
debug("%#lx: Destroying mutex", this);
|
||||||
|
assert(this->Holder == nullptr);
|
||||||
|
assert(this->Waiting.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user