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