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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if DEVICE_SERIAL
|
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "UARTSerial.h"
|
#include "UARTSerial.h"
|
||||||
|
|
@ -80,16 +80,16 @@ off_t UARTSerial::seek(off_t offset, int whence)
|
||||||
|
|
||||||
int UARTSerial::sync()
|
int UARTSerial::sync()
|
||||||
{
|
{
|
||||||
lock();
|
api_lock();
|
||||||
|
|
||||||
while (!_txbuf.empty()) {
|
while (!_txbuf.empty()) {
|
||||||
unlock();
|
api_unlock();
|
||||||
// Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
|
// Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
|
||||||
wait_ms(1);
|
wait_ms(1);
|
||||||
lock();
|
api_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock();
|
api_unlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -111,16 +111,16 @@ ssize_t UARTSerial::write(const void* buffer, size_t length)
|
||||||
size_t data_written = 0;
|
size_t data_written = 0;
|
||||||
const char *buf_ptr = static_cast<const char *>(buffer);
|
const char *buf_ptr = static_cast<const char *>(buffer);
|
||||||
|
|
||||||
lock();
|
api_lock();
|
||||||
|
|
||||||
while (_txbuf.full()) {
|
while (_txbuf.full()) {
|
||||||
if (!_blocking) {
|
if (!_blocking) {
|
||||||
unlock();
|
api_unlock();
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
unlock();
|
api_unlock();
|
||||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||||
lock();
|
api_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_written < length && !_txbuf.full()) {
|
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();
|
core_util_critical_section_exit();
|
||||||
|
|
||||||
unlock();
|
api_unlock();
|
||||||
|
|
||||||
return data_written;
|
return data_written;
|
||||||
}
|
}
|
||||||
|
|
@ -149,16 +149,16 @@ ssize_t UARTSerial::read(void* buffer, size_t length)
|
||||||
|
|
||||||
char *ptr = static_cast<char *>(buffer);
|
char *ptr = static_cast<char *>(buffer);
|
||||||
|
|
||||||
lock();
|
api_lock();
|
||||||
|
|
||||||
while (_rxbuf.empty()) {
|
while (_rxbuf.empty()) {
|
||||||
if (!_blocking) {
|
if (!_blocking) {
|
||||||
unlock();
|
api_unlock();
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
unlock();
|
api_unlock();
|
||||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||||
lock();
|
api_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (data_read < length && !_rxbuf.empty()) {
|
while (data_read < length && !_rxbuf.empty()) {
|
||||||
|
|
@ -166,7 +166,7 @@ ssize_t UARTSerial::read(void* buffer, size_t length)
|
||||||
data_read++;
|
data_read++;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock();
|
api_unlock();
|
||||||
|
|
||||||
return data_read;
|
return data_read;
|
||||||
}
|
}
|
||||||
|
|
@ -205,12 +205,24 @@ short UARTSerial::poll(short events) const {
|
||||||
return revents;
|
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();
|
_mutex.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UARTSerial::unlock(void)
|
void UARTSerial::api_unlock(void)
|
||||||
{
|
{
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
@ -262,4 +274,4 @@ void UARTSerial::tx_irq(void)
|
||||||
|
|
||||||
} //namespace mbed
|
} //namespace mbed
|
||||||
|
|
||||||
#endif //DEVICE_SERIAL
|
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
#if DEVICE_SERIAL
|
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||||
|
|
||||||
#include "FileHandle.h"
|
#include "FileHandle.h"
|
||||||
#include "SerialBase.h"
|
#include "SerialBase.h"
|
||||||
|
|
@ -58,7 +58,7 @@ public:
|
||||||
/** Write the contents of a buffer to a file
|
/** Write the contents of a buffer to a file
|
||||||
*
|
*
|
||||||
* @param buffer The buffer to write from
|
* @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
|
* @return The number of bytes written, negative error on failure
|
||||||
*/
|
*/
|
||||||
virtual ssize_t write(const void* buffer, size_t length);
|
virtual ssize_t write(const void* buffer, size_t length);
|
||||||
|
|
@ -72,17 +72,11 @@ public:
|
||||||
* * If any data is available, call returns immediately
|
* * If any data is available, call returns immediately
|
||||||
*
|
*
|
||||||
* @param buffer The buffer to read in to
|
* @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
|
* @return The number of bytes read, 0 at end of file, negative error on failure
|
||||||
*/
|
*/
|
||||||
virtual ssize_t read(void* buffer, size_t length);
|
virtual ssize_t read(void* buffer, size_t length);
|
||||||
|
|
||||||
/** Acquire mutex */
|
|
||||||
virtual void lock(void);
|
|
||||||
|
|
||||||
/** Release mutex */
|
|
||||||
virtual void unlock(void);
|
|
||||||
|
|
||||||
/** Close a file
|
/** Close a file
|
||||||
*
|
*
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure
|
||||||
|
|
@ -159,6 +153,18 @@ public:
|
||||||
|
|
||||||
private:
|
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
|
/** Software serial buffers
|
||||||
* By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
|
* 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 wake(void);
|
||||||
|
|
||||||
void dcd_irq(void);
|
void dcd_irq(void);
|
||||||
|
|
||||||
};
|
};
|
||||||
} //namespace mbed
|
} //namespace mbed
|
||||||
|
|
||||||
#endif //DEVICE_SERIAL
|
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||||
#endif //MBED_UARTSERIAL_H
|
#endif //MBED_UARTSERIAL_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue