mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #4538 from hasnainvirk/avoid_mtx_lock
Avoid lock collision b/w SerialBase & UARTSerialpull/4639/head
commit
17ae9b923e
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if DEVICE_SERIAL
|
||||
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||
|
||||
#include <errno.h>
|
||||
#include "UARTSerial.h"
|
||||
|
|
@ -80,16 +80,16 @@ off_t UARTSerial::seek(off_t offset, int whence)
|
|||
|
||||
int UARTSerial::sync()
|
||||
{
|
||||
lock();
|
||||
api_lock();
|
||||
|
||||
while (!_txbuf.empty()) {
|
||||
unlock();
|
||||
api_unlock();
|
||||
// Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
|
||||
wait_ms(1);
|
||||
lock();
|
||||
api_lock();
|
||||
}
|
||||
|
||||
unlock();
|
||||
api_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -111,16 +111,16 @@ ssize_t UARTSerial::write(const void* buffer, size_t length)
|
|||
size_t data_written = 0;
|
||||
const char *buf_ptr = static_cast<const char *>(buffer);
|
||||
|
||||
lock();
|
||||
api_lock();
|
||||
|
||||
while (_txbuf.full()) {
|
||||
if (!_blocking) {
|
||||
unlock();
|
||||
api_unlock();
|
||||
return -EAGAIN;
|
||||
}
|
||||
unlock();
|
||||
api_unlock();
|
||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||
lock();
|
||||
api_lock();
|
||||
}
|
||||
|
||||
while (data_written < length && !_txbuf.full()) {
|
||||
|
|
@ -138,7 +138,7 @@ ssize_t UARTSerial::write(const void* buffer, size_t length)
|
|||
}
|
||||
core_util_critical_section_exit();
|
||||
|
||||
unlock();
|
||||
api_unlock();
|
||||
|
||||
return data_written;
|
||||
}
|
||||
|
|
@ -149,16 +149,16 @@ ssize_t UARTSerial::read(void* buffer, size_t length)
|
|||
|
||||
char *ptr = static_cast<char *>(buffer);
|
||||
|
||||
lock();
|
||||
api_lock();
|
||||
|
||||
while (_rxbuf.empty()) {
|
||||
if (!_blocking) {
|
||||
unlock();
|
||||
api_unlock();
|
||||
return -EAGAIN;
|
||||
}
|
||||
unlock();
|
||||
api_unlock();
|
||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||
lock();
|
||||
api_lock();
|
||||
}
|
||||
|
||||
while (data_read < length && !_rxbuf.empty()) {
|
||||
|
|
@ -166,7 +166,7 @@ ssize_t UARTSerial::read(void* buffer, size_t length)
|
|||
data_read++;
|
||||
}
|
||||
|
||||
unlock();
|
||||
api_unlock();
|
||||
|
||||
return data_read;
|
||||
}
|
||||
|
|
@ -205,12 +205,24 @@ short UARTSerial::poll(short events) const {
|
|||
return revents;
|
||||
}
|
||||
|
||||
void UARTSerial::lock(void)
|
||||
void UARTSerial::lock()
|
||||
{
|
||||
// This is the override for SerialBase.
|
||||
// No lock required as we only use SerialBase from interrupt or from
|
||||
// inside our own critical section.
|
||||
}
|
||||
|
||||
void UARTSerial::unlock()
|
||||
{
|
||||
// This is the override for SerialBase.
|
||||
}
|
||||
|
||||
void UARTSerial::api_lock(void)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void UARTSerial::unlock(void)
|
||||
void UARTSerial::api_unlock(void)
|
||||
{
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
|
@ -262,4 +274,4 @@ void UARTSerial::tx_irq(void)
|
|||
|
||||
} //namespace mbed
|
||||
|
||||
#endif //DEVICE_SERIAL
|
||||
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if DEVICE_SERIAL
|
||||
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "FileHandle.h"
|
||||
#include "SerialBase.h"
|
||||
|
|
@ -58,7 +58,7 @@ public:
|
|||
/** Write the contents of a buffer to a file
|
||||
*
|
||||
* @param buffer The buffer to write from
|
||||
* @param size The number of bytes to write
|
||||
* @param length The number of bytes to write
|
||||
* @return The number of bytes written, negative error on failure
|
||||
*/
|
||||
virtual ssize_t write(const void* buffer, size_t length);
|
||||
|
|
@ -72,17 +72,11 @@ public:
|
|||
* * If any data is available, call returns immediately
|
||||
*
|
||||
* @param buffer The buffer to read in to
|
||||
* @param size The number of bytes to read
|
||||
* @param length The number of bytes to read
|
||||
* @return The number of bytes read, 0 at end of file, negative error on failure
|
||||
*/
|
||||
virtual ssize_t read(void* buffer, size_t length);
|
||||
|
||||
/** Acquire mutex */
|
||||
virtual void lock(void);
|
||||
|
||||
/** Release mutex */
|
||||
virtual void unlock(void);
|
||||
|
||||
/** Close a file
|
||||
*
|
||||
* @return 0 on success, negative error code on failure
|
||||
|
|
@ -159,6 +153,18 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
/** SerialBase lock override */
|
||||
virtual void lock(void);
|
||||
|
||||
/** SerialBase unlock override */
|
||||
virtual void unlock(void);
|
||||
|
||||
/** Acquire mutex */
|
||||
virtual void api_lock(void);
|
||||
|
||||
/** Release mutex */
|
||||
virtual void api_unlock(void);
|
||||
|
||||
/** Software serial buffers
|
||||
* By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
|
||||
*/
|
||||
|
|
@ -191,8 +197,9 @@ private:
|
|||
void wake(void);
|
||||
|
||||
void dcd_irq(void);
|
||||
|
||||
};
|
||||
} //namespace mbed
|
||||
|
||||
#endif //DEVICE_SERIAL
|
||||
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||
#endif //MBED_UARTSERIAL_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue