VDev & CDev: dynamically allocate & resize _pollset array

In most cases, really only 1 element is needed. The dynamic allocation
handles cases where more are necessary. This is all done within a locked
state, so no races can occur.

Frees roughly 2.3KB RAM.
This commit is contained in:
Beat Küng 2016-11-11 14:59:27 +01:00 committed by Lorenz Meier
parent 14fd1b8693
commit dc6ca7c372
4 changed files with 64 additions and 16 deletions

View File

@ -98,11 +98,10 @@ CDev::CDev(const char *name,
// private
_devname(devname),
_registered(false),
_open_count(0)
_max_pollwaiters(0),
_open_count(0),
_pollset(nullptr)
{
for (unsigned i = 0; i < _max_pollwaiters; i++) {
_pollset[i] = nullptr;
}
}
CDev::~CDev()
@ -110,6 +109,10 @@ CDev::~CDev()
if (_registered) {
unregister_driver(_devname);
}
if (_pollset) {
delete[](_pollset);
}
}
int
@ -385,7 +388,29 @@ CDev::store_poll_waiter(struct pollfd *fds)
}
}
return ENOMEM;
/* No free slot found. Resize the pollset */
if (_max_pollwaiters >= 256 / 2) { //_max_pollwaiters is uint8_t
return -ENOMEM;
}
const uint8_t new_count = _max_pollwaiters > 0 ? _max_pollwaiters * 2 : 1;
pollfd **new_pollset = new pollfd*[new_count];
if (!new_pollset) {
return -ENOMEM;
}
if (_max_pollwaiters > 0) {
memset(new_pollset + _max_pollwaiters, 0, sizeof(pollfd *) * (new_count - _max_pollwaiters));
memcpy(new_pollset, _pollset, sizeof(pollfd *) * _max_pollwaiters);
delete[](_pollset);
}
_pollset = new_pollset;
_pollset[_max_pollwaiters] = fds;
_max_pollwaiters = new_count;
return OK;
}
int

View File

@ -451,13 +451,13 @@ protected:
bool _pub_blocked; /**< true if publishing should be blocked */
private:
static const unsigned _max_pollwaiters = 8;
const char *_devname; /**< device node name */
bool _registered; /**< true if device name was registered */
uint8_t _max_pollwaiters; /**< size of the _pollset array */
uint16_t _open_count; /**< number of successful opens */
struct pollfd *_pollset[_max_pollwaiters];
struct pollfd **_pollset;
/**
* Store a pollwaiter in a slot where we can find it later.

View File

@ -84,13 +84,11 @@ VDev::VDev(const char *name,
// private
_devname(devname),
_registered(false),
_open_count(0)
_max_pollwaiters(0),
_open_count(0),
_pollset(nullptr)
{
PX4_DEBUG("VDev::VDev");
for (unsigned i = 0; i < _max_pollwaiters; i++) {
_pollset[i] = nullptr;
}
}
VDev::~VDev()
@ -100,6 +98,10 @@ VDev::~VDev()
if (_registered) {
unregister_driver(_devname);
}
if (_pollset) {
delete[](_pollset);
}
}
int
@ -486,7 +488,29 @@ VDev::store_poll_waiter(px4_pollfd_struct_t *fds)
}
}
return -ENOMEM;
/* No free slot found. Resize the pollset */
if (_max_pollwaiters >= 256 / 2) { //_max_pollwaiters is uint8_t
return -ENOMEM;
}
const uint8_t new_count = _max_pollwaiters > 0 ? _max_pollwaiters * 2 : 1;
px4_pollfd_struct_t **new_pollset = new px4_pollfd_struct_t *[new_count];
if (!new_pollset) {
return -ENOMEM;
}
if (_max_pollwaiters > 0) {
memset(new_pollset + _max_pollwaiters, 0, sizeof(px4_pollfd_struct_t *) * (new_count - _max_pollwaiters));
memcpy(new_pollset, _pollset, sizeof(px4_pollfd_struct_t *) * _max_pollwaiters);
delete[](_pollset);
}
_pollset = new_pollset;
_pollset[_max_pollwaiters] = fds;
_max_pollwaiters = new_count;
return PX4_OK;
}
int

View File

@ -425,13 +425,12 @@ protected:
bool _pub_blocked; /**< true if publishing should be blocked */
private:
static const unsigned _max_pollwaiters = 8;
const char *_devname; /**< device node name */
bool _registered; /**< true if device name was registered */
uint8_t _max_pollwaiters; /**< size of the _pollset array */
unsigned _open_count; /**< number of successful opens */
px4_pollfd_struct_t *_pollset[_max_pollwaiters];
px4_pollfd_struct_t **_pollset;
/**
* Store a pollwaiter in a slot where we can find it later.