Skip to content
Snippets Groups Projects
Commit f3a64920 authored by Federico's avatar Federico
Browse files

Simplify code and reduce code size by removing IRQwait

parent 98e36e44
Branches
No related tags found
No related merge requests found
...@@ -54,8 +54,8 @@ static inline void IRQdoMutexLock(pthread_mutex_t *mutex, ...@@ -54,8 +54,8 @@ static inline void IRQdoMutexLock(pthread_mutex_t *mutex,
} }
//This check is very important. Without this attempting to lock the same //This check is very important. Without this attempting to lock the same
//mutex twice won't cause a deadlock because the Thread::IRQwait() is //mutex twice won't cause a deadlock because the wait is enclosed in a
//enclosed in a while(owner!=p) which is immeditely false. //while(owner!=p) which is immeditely false.
if(mutex->owner==p) if(mutex->owner==p)
{ {
if(mutex->recursive>=0) if(mutex->recursive>=0)
...@@ -77,17 +77,8 @@ static inline void IRQdoMutexLock(pthread_mutex_t *mutex, ...@@ -77,17 +77,8 @@ static inline void IRQdoMutexLock(pthread_mutex_t *mutex,
mutex->last=&waiting; mutex->last=&waiting;
} }
//The while is necessary because some other thread might call wakeup() //The while is necessary to protect against spurious wakeups
//on this thread. So the thread can wakeup also for other reasons not while(mutex->owner!=p) Thread::IRQenableIrqAndWait(d);
//related to the mutex becoming free
while(mutex->owner!=p)
{
Thread::IRQwait();//Returns immediately
{
FastInterruptEnableLock eLock(d);
Thread::yield(); //Now the IRQwait becomes effective
}
}
} }
/** /**
...@@ -113,8 +104,8 @@ static inline void IRQdoMutexLockToDepth(pthread_mutex_t *mutex, ...@@ -113,8 +104,8 @@ static inline void IRQdoMutexLockToDepth(pthread_mutex_t *mutex,
} }
//This check is very important. Without this attempting to lock the same //This check is very important. Without this attempting to lock the same
//mutex twice won't cause a deadlock because the Thread::IRQwait() is //mutex twice won't cause a deadlock because the wait is enclosed in a
//enclosed in a while(owner!=p) which is immeditely false. //while(owner!=p) which is immeditely false.
if(mutex->owner==p) if(mutex->owner==p)
{ {
if(mutex->recursive>=0) if(mutex->recursive>=0)
...@@ -136,17 +127,8 @@ static inline void IRQdoMutexLockToDepth(pthread_mutex_t *mutex, ...@@ -136,17 +127,8 @@ static inline void IRQdoMutexLockToDepth(pthread_mutex_t *mutex,
mutex->last=&waiting; mutex->last=&waiting;
} }
//The while is necessary because some other thread might call wakeup() //The while is necessary to protect against spurious wakeups
//on this thread. So the thread can wakeup also for other reasons not while(mutex->owner!=p) Thread::IRQenableIrqAndWait(d);
//related to the mutex becoming free
while(mutex->owner!=p)
{
Thread::IRQwait();//Returns immediately
{
FastInterruptEnableLock eLock(d);
Thread::yield(); //Now the IRQwait becomes effective
}
}
if(mutex->recursive>=0) mutex->recursive=depth; if(mutex->recursive>=0) mutex->recursive=depth;
} }
......
/*************************************************************************** /***************************************************************************
* Copyright (C) 2014 by Terraneo Federico * * Copyright (C) 2014 - 2023 by Terraneo Federico *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> * * along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/ ***************************************************************************/
#ifndef QUEUE_H #pragma once
#define QUEUE_H
#include "kernel.h" #include "kernel.h"
#include "error.h" #include "error.h"
...@@ -57,7 +56,7 @@ public: ...@@ -57,7 +56,7 @@ public:
/** /**
* Constructor, create a new empty queue. * Constructor, create a new empty queue.
*/ */
Queue() : waiting(0), numElem(0), putPos(0), getPos(0) {} Queue() : waiting(nullptr), numElem(0), putPos(0), getPos(0) {}
/** /**
* \return true if the queue is empty * \return true if the queue is empty
...@@ -178,7 +177,7 @@ private: ...@@ -178,7 +177,7 @@ private:
{ {
if(!waiting) return; if(!waiting) return;
waiting->IRQwakeup();//Wakeup eventual waiting thread waiting->IRQwakeup();//Wakeup eventual waiting thread
waiting=0; waiting=nullptr;
} }
//Queue data //Queue data
...@@ -197,11 +196,7 @@ void Queue<T,len>::waitUntilNotEmpty() ...@@ -197,11 +196,7 @@ void Queue<T,len>::waitUntilNotEmpty()
while(isEmpty()) while(isEmpty())
{ {
waiting=Thread::IRQgetCurrentThread(); waiting=Thread::IRQgetCurrentThread();
Thread::IRQwait(); Thread::IRQenableIrqAndWait(dLock);
{
FastInterruptEnableLock eLock(dLock);
Thread::yield();
}
IRQwakeWaitingThread(); IRQwakeWaitingThread();
} }
} }
...@@ -214,11 +209,7 @@ void Queue<T,len>::waitUntilNotFull() ...@@ -214,11 +209,7 @@ void Queue<T,len>::waitUntilNotFull()
while(isFull()) while(isFull())
{ {
waiting=Thread::IRQgetCurrentThread(); waiting=Thread::IRQgetCurrentThread();
Thread::IRQwait(); Thread::IRQenableIrqAndWait(dLock);
{
FastInterruptEnableLock eLock(dLock);
Thread::yield();
}
IRQwakeWaitingThread(); IRQwakeWaitingThread();
} }
} }
...@@ -231,11 +222,7 @@ void Queue<T,len>::get(T& elem) ...@@ -231,11 +222,7 @@ void Queue<T,len>::get(T& elem)
while(isEmpty()) while(isEmpty())
{ {
waiting=Thread::IRQgetCurrentThread(); waiting=Thread::IRQgetCurrentThread();
Thread::IRQwait(); Thread::IRQenableIrqAndWait(dLock);
{
FastInterruptEnableLock eLock(dLock);
Thread::yield();
}
IRQwakeWaitingThread(); IRQwakeWaitingThread();
} }
numElem--; numElem--;
...@@ -251,11 +238,7 @@ void Queue<T,len>::put(const T& elem) ...@@ -251,11 +238,7 @@ void Queue<T,len>::put(const T& elem)
while(isFull()) while(isFull())
{ {
waiting=Thread::IRQgetCurrentThread(); waiting=Thread::IRQgetCurrentThread();
Thread::IRQwait(); Thread::IRQenableIrqAndWait(dLock);
{
FastInterruptEnableLock eLock(dLock);
Thread::yield();
}
IRQwakeWaitingThread(); IRQwakeWaitingThread();
} }
numElem++; numElem++;
...@@ -550,5 +533,3 @@ template<typename T, unsigned int size> class BufferQueue<T,size,1> {}; ...@@ -550,5 +533,3 @@ template<typename T, unsigned int size> class BufferQueue<T,size,1> {};
*/ */
} //namespace miosix } //namespace miosix
#endif //QUEUE_H
...@@ -61,8 +61,8 @@ void Mutex::PKlock(PauseKernelLock& dLock) ...@@ -61,8 +61,8 @@ void Mutex::PKlock(PauseKernelLock& dLock)
} }
//This check is very important. Without this attempting to lock the same //This check is very important. Without this attempting to lock the same
//mutex twice won't cause a deadlock because the Thread::IRQwait() is //mutex twice won't cause a deadlock because the wait is enclosed in a
//enclosed in a while(owner!=p) which is immeditely false. //while(owner!=p) which is immeditely false.
if(owner==p) if(owner==p)
{ {
if(recursiveDepth>=0) if(recursiveDepth>=0)
...@@ -93,24 +93,8 @@ void Mutex::PKlock(PauseKernelLock& dLock) ...@@ -93,24 +93,8 @@ void Mutex::PKlock(PauseKernelLock& dLock)
} }
} }
//The while is necessary because some other thread might call wakeup() //The while is necessary to protect against spurious wakeups
//on this thread. So the thread can wakeup also for other reasons not while(owner!=p) Thread::PKrestartKernelAndWait(dLock);
//related to the mutex becoming free
while(owner!=p)
{
//Wait can only be called with kernel started, while IRQwait can
//only be called with interupts disabled, so that's why interrupts
//are disabled
{
FastInterruptDisableLock l;
Thread::IRQwait();//Return immediately
}
{
RestartKernelLock eLock(dLock);
//Now the IRQwait becomes effective
Thread::yield();
}
}
} }
void Mutex::PKlockToDepth(PauseKernelLock& dLock, unsigned int depth) void Mutex::PKlockToDepth(PauseKernelLock& dLock, unsigned int depth)
...@@ -130,8 +114,8 @@ void Mutex::PKlockToDepth(PauseKernelLock& dLock, unsigned int depth) ...@@ -130,8 +114,8 @@ void Mutex::PKlockToDepth(PauseKernelLock& dLock, unsigned int depth)
} }
//This check is very important. Without this attempting to lock the same //This check is very important. Without this attempting to lock the same
//mutex twice won't cause a deadlock because the Thread::IRQwait() is //mutex twice won't cause a deadlock because the wait is enclosed in a
//enclosed in a while(owner!=p) which is immeditely false. //while(owner!=p) which is immeditely false.
if(owner==p) if(owner==p)
{ {
if(recursiveDepth>=0) if(recursiveDepth>=0)
...@@ -162,24 +146,8 @@ void Mutex::PKlockToDepth(PauseKernelLock& dLock, unsigned int depth) ...@@ -162,24 +146,8 @@ void Mutex::PKlockToDepth(PauseKernelLock& dLock, unsigned int depth)
} }
} }
//The while is necessary because some other thread might call wakeup() //The while is necessary to protect against spurious wakeups
//on this thread. So the thread can wakeup also for other reasons not while(owner!=p) Thread::PKrestartKernelAndWait(dLock);
//related to the mutex becoming free
while(owner!=p)
{
//Wait can only be called with kernel started, while IRQwait can
//only be called with interupts disabled, so that's why interrupts
//are disabled
{
FastInterruptDisableLock l;
Thread::IRQwait();//Return immediately
}
{
RestartKernelLock eLock(dLock);
//Now the IRQwait becomes effective
Thread::yield();
}
}
if(recursiveDepth>=0) recursiveDepth=depth; if(recursiveDepth>=0) recursiveDepth=depth;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment