Skip to content

Commit

Permalink
uORBDeviceNode.cpp: Use semaphore as node lock, instead of critical s…
Browse files Browse the repository at this point in the history
…ection

A critical section is not a lock, it cannot be used to lock the device
node as if the task that needs to lock the node yields, interrupts can
get re-enabled which means the node is not locked anymore.
  • Loading branch information
pussuw authored and jnippula committed May 2, 2024
1 parent 789f5e5 commit 83ca089
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 38 deletions.
53 changes: 20 additions & 33 deletions platforms/common/uORB/uORBDeviceNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,6 @@
#include <px4_platform_common/sem.hpp>
#include <drivers/drv_hrt.h>

// This is a speed optimization for nuttx flat build
#ifdef CONFIG_BUILD_FLAT
#define ATOMIC_ENTER irqstate_t flags = px4_enter_critical_section()
#define ATOMIC_LEAVE px4_leave_critical_section(flags)
#else
#define ATOMIC_ENTER lock()
#define ATOMIC_LEAVE unlock()
#endif

// Every subscriber thread has it's own list of cached subscriptions
uORB::DeviceNode::MappingCache::MappingCacheListItem *uORB::DeviceNode::MappingCache::g_cache =
nullptr;
Expand Down Expand Up @@ -411,6 +402,12 @@ uORB::DeviceNode::DeviceNode(const ORB_ID id, const uint8_t instance, const char
_orb_id(id),
_instance(instance)
{
int ret = px4_sem_init(&_lock, 1, 1);

if (ret != 0) {
PX4_DEBUG("SEM INIT FAIL: ret %d", ret);
}

#if defined(CONFIG_BUILD_FLAT)
_devname = strdup(path);
#else
Expand All @@ -420,13 +417,6 @@ uORB::DeviceNode::DeviceNode(const ORB_ID id, const uint8_t instance, const char
}

strncpy(_devname, path, sizeof(_devname));

int ret = px4_sem_init(&_lock, 1, 1);

if (ret != 0) {
PX4_DEBUG("SEM INIT FAIL: ret %d", ret);
}

#endif
}

Expand All @@ -447,9 +437,8 @@ uORB::DeviceNode::~DeviceNode()
}

free(_devname);
#else
px4_sem_destroy(&_lock);
#endif
px4_sem_destroy(&_lock);
}

/* Map the node data to the memory space of publisher or subscriber */
Expand Down Expand Up @@ -526,13 +515,13 @@ bool uORB::DeviceNode::copy(void *dst, orb_advert_t &handle, unsigned &generatio
size_t o_size = get_meta()->o_size;
size_t data_size = _queue_size * o_size;

ATOMIC_ENTER;
lock();

if (data_size != handle.data_size) {
remap_data(handle, data_size, false);

if (node_data(handle) == nullptr) {
ATOMIC_LEAVE;
unlock();
return false;
}
}
Expand Down Expand Up @@ -562,7 +551,7 @@ bool uORB::DeviceNode::copy(void *dst, orb_advert_t &handle, unsigned &generatio
++generation;
}

ATOMIC_LEAVE;
unlock();

return true;

Expand All @@ -577,14 +566,14 @@ uORB::DeviceNode::write(const char *buffer, const orb_metadata *meta, orb_advert
size_t data_size = _queue_size * o_size;

/* Perform an atomic copy. */
ATOMIC_ENTER;
lock();

if (data_size != handle.data_size) {
remap_data(handle, data_size, true);
}

if (node_data(handle) == nullptr) {
ATOMIC_LEAVE;
unlock();
return -ENOMEM;
}

Expand Down Expand Up @@ -636,7 +625,7 @@ uORB::DeviceNode::write(const char *buffer, const orb_metadata *meta, orb_advert
cb = callbacks.next(cb);
}

ATOMIC_LEAVE;
unlock();

return o_size;
}
Expand Down Expand Up @@ -701,14 +690,13 @@ int16_t uORB::DeviceNode::topic_advertised(const orb_metadata *meta)
bool
uORB::DeviceNode::print_statistics(int max_topic_length)
{

ATOMIC_ENTER;
lock();

const uint8_t instance = get_instance();
const int8_t sub_count = subscriber_count();
const uint8_t queue_size = get_queue_size();

ATOMIC_LEAVE;
unlock();

const orb_metadata *meta = get_meta();

Expand Down Expand Up @@ -863,17 +851,16 @@ uORB::DeviceNode::_register_callback(uORB::SubscriptionCallback *cb_sub,

IndexedStackHandle<CB_LIST_T> callbacks(_callbacks);

ATOMIC_ENTER;
lock();

cb_handle = callbacks.pop_free();
EventWaitItem *item = callbacks.peek(cb_handle);

#ifdef CONFIG_BUILD_FLAT
/* With flat mode it is OK to allocate more items for the list */

if (!item) {
px4_leave_critical_section(flags);
item = new EventWaitItem;
flags = px4_enter_critical_section();
cb_handle = item;
}

Expand All @@ -894,7 +881,7 @@ uORB::DeviceNode::_register_callback(uORB::SubscriptionCallback *cb_sub,
PX4_ERR("register fail\n");
}

ATOMIC_LEAVE;
unlock();

return uorb_cb_handle_valid(cb_handle);
}
Expand All @@ -908,7 +895,7 @@ uORB::DeviceNode::_unregister_callback(uorb_cb_handle_t &cb_handle)
#endif
int ret = 0;

ATOMIC_ENTER;
lock();

bool ret_rm = callbacks.rm(cb_handle);

Expand All @@ -923,7 +910,7 @@ uORB::DeviceNode::_unregister_callback(uorb_cb_handle_t &cb_handle)
cb_handle = UORB_INVALID_CB_HANDLE;
}

ATOMIC_LEAVE;
unlock();

return ret;
}
9 changes: 4 additions & 5 deletions platforms/common/uORB/uORBDeviceNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,6 @@ class DeviceNode
uint32_t interval_us, uorb_cb_handle_t &cb_handle);
int _unregister_callback(uorb_cb_handle_t &cb_handle);

#ifdef CONFIG_BUILD_FLAT
char *_devname;
void *_data{nullptr};
#else

/**
* Mutex for protecting node's internal data
*/
Expand All @@ -364,6 +359,10 @@ class DeviceNode
void unlock() { px4_sem_post(&_lock); }
px4_sem_t _lock; /**< lock to protect access to all class members */

#ifdef CONFIG_BUILD_FLAT
char *_devname;
void *_data{nullptr};
#else
char _devname[NAME_MAX + 1];
#endif
};
Expand Down

0 comments on commit 83ca089

Please sign in to comment.