uORBDeviceNode: use px4::atomic instead of volatile for _generation

_generation is read in a multi-threaded context w/o locking.
This commit is contained in:
Beat Küng 2019-11-20 08:15:34 +01:00
parent 20ede04cf1
commit 0e9fde2055
2 changed files with 13 additions and 10 deletions

View File

@ -170,14 +170,15 @@ uORB::DeviceNode::copy_locked(void *dst, unsigned &generation)
bool updated = false;
if ((dst != nullptr) && (_data != nullptr)) {
unsigned current_generation = _generation.load();
if (_generation > generation + _queue_size) {
if (current_generation > generation + _queue_size) {
// Reader is too far behind: some messages are lost
_lost_messages += _generation - (generation + _queue_size);
generation = _generation - _queue_size;
_lost_messages += current_generation - (generation + _queue_size);
generation = current_generation - _queue_size;
}
if ((_generation == generation) && (generation > 0)) {
if ((current_generation == generation) && (generation > 0)) {
/* The subscriber already read the latest message, but nothing new was published yet.
* Return the previous message
*/
@ -186,7 +187,7 @@ uORB::DeviceNode::copy_locked(void *dst, unsigned &generation)
memcpy(dst, _data + (_meta->o_size * (generation % _queue_size)), _meta->o_size);
if (generation < _generation) {
if (generation < current_generation) {
++generation;
}
@ -299,12 +300,13 @@ uORB::DeviceNode::write(cdev::file_t *filp, const char *buffer, size_t buflen)
/* Perform an atomic copy. */
ATOMIC_ENTER;
memcpy(_data + (_meta->o_size * (_generation % _queue_size)), buffer, _meta->o_size);
/* wrap-around happens after ~49 days, assuming a publisher rate of 1 kHz */
unsigned generation = _generation.fetch_add(1);
memcpy(_data + (_meta->o_size * (generation % _queue_size)), buffer, _meta->o_size);
/* update the timestamp and generation count */
_last_update = hrt_absolute_time();
/* wrap-around happens after ~49 days, assuming a publisher rate of 1 kHz */
_generation++;
_published = true;

View File

@ -39,6 +39,7 @@
#include <lib/cdev/CDev.hpp>
#include <containers/List.hpp>
#include <px4_atomic.h>
namespace uORB
{
@ -185,7 +186,7 @@ public:
uint32_t lost_message_count() const { return _lost_messages; }
unsigned published_message_count() const { return _generation; }
unsigned published_message_count() const { return _generation.load(); }
const orb_metadata *get_meta() const { return _meta; }
@ -267,7 +268,7 @@ private:
const uint8_t _instance; /**< orb multi instance identifier */
uint8_t *_data{nullptr}; /**< allocated object buffer */
hrt_abstime _last_update{0}; /**< time the object was last updated */
volatile unsigned _generation{0}; /**< object generation count */
px4::atomic<unsigned> _generation{0}; /**< object generation count */
List<uORB::SubscriptionCallback *> _callbacks;
uint8_t _priority; /**< priority of the topic */
bool _published{false}; /**< has ever data been published */