Browse Source

More noexcept stuff

tags/1.9.4
falkTX 12 years ago
parent
commit
7189070c6e
4 changed files with 122 additions and 60 deletions
  1. +17
    -17
      source/modules/rtmempool/list.h
  2. +15
    -5
      source/utils/CarlaLibCounter.hpp
  3. +52
    -22
      source/utils/LinkedList.hpp
  4. +38
    -16
      source/utils/RtLinkedList.hpp

+ 17
- 17
source/modules/rtmempool/list.h View File

@@ -86,7 +86,7 @@ struct list_head {
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)

static inline void INIT_LIST_HEAD(struct list_head *list)
static inline void INIT_LIST_HEAD(struct list_head *list) __THROW
{
list->next = list;
list->prev = list;
@@ -98,7 +98,7 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new_, struct list_head *prev, struct list_head *next)
static inline void __list_add(struct list_head *new_, struct list_head *prev, struct list_head *next) __THROW
{
next->prev = new_;
new_->next = next;
@@ -114,7 +114,7 @@ static inline void __list_add(struct list_head *new_, struct list_head *prev, st
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new_, struct list_head *head)
static inline void list_add(struct list_head *new_, struct list_head *head) __THROW
{
__list_add(new_, head, head->next);
}
@@ -127,7 +127,7 @@ static inline void list_add(struct list_head *new_, struct list_head *head)
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new_, struct list_head *head)
static inline void list_add_tail(struct list_head *new_, struct list_head *head) __THROW
{
__list_add(new_, head->prev, head);
}
@@ -139,7 +139,7 @@ static inline void list_add_tail(struct list_head *new_, struct list_head *head)
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
static inline void __list_del(struct list_head *prev, struct list_head *next) __THROW
{
next->prev = prev;
prev->next = next;
@@ -151,7 +151,7 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
static inline void list_del(struct list_head *entry) __THROW
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head*)LIST_POISON1;
@@ -162,7 +162,7 @@ static inline void list_del(struct list_head *entry)
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
static inline void list_del_init(struct list_head *entry) __THROW
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
@@ -173,7 +173,7 @@ static inline void list_del_init(struct list_head *entry)
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
static inline void list_move(struct list_head *list, struct list_head *head) __THROW
{
__list_del(list->prev, list->next);
list_add(list, head);
@@ -184,7 +184,7 @@ static inline void list_move(struct list_head *list, struct list_head *head)
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list, struct list_head *head)
static inline void list_move_tail(struct list_head *list, struct list_head *head) __THROW
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
@@ -194,7 +194,7 @@ static inline void list_move_tail(struct list_head *list, struct list_head *head
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
static inline int list_empty(const struct list_head *head) __THROW
{
return head->next == head;
}
@@ -211,13 +211,13 @@ static inline int list_empty(const struct list_head *head)
*
* @head: the list to test.
*/
static inline int list_empty_careful(const struct list_head *head)
static inline int list_empty_careful(const struct list_head *head) __THROW
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}

static inline void __list_splice(struct list_head *list, struct list_head *head)
static inline void __list_splice(struct list_head *list, struct list_head *head) __THROW
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
@@ -230,7 +230,7 @@ static inline void __list_splice(struct list_head *list, struct list_head *head)
at->prev = last;
}

static inline void __list_splice_tail(struct list_head *list, struct list_head *head)
static inline void __list_splice_tail(struct list_head *list, struct list_head *head) __THROW
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
@@ -248,7 +248,7 @@ static inline void __list_splice_tail(struct list_head *list, struct list_head *
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
static inline void list_splice(struct list_head *list, struct list_head *head) __THROW
{
if (!list_empty(list))
__list_splice(list, head);
@@ -261,7 +261,7 @@ static inline void list_splice(struct list_head *list, struct list_head *head)
*
* @list goes to the end (at head->prev)
*/
static inline void list_splice_tail(struct list_head *list, struct list_head *head)
static inline void list_splice_tail(struct list_head *list, struct list_head *head) __THROW
{
if (!list_empty(list))
__list_splice_tail(list, head);
@@ -274,7 +274,7 @@ static inline void list_splice_tail(struct list_head *list, struct list_head *he
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list, struct list_head *head)
static inline void list_splice_init(struct list_head *list, struct list_head *head) __THROW
{
if (!list_empty(list)) {
__list_splice(list, head);
@@ -290,7 +290,7 @@ static inline void list_splice_init(struct list_head *list, struct list_head *he
* The list at @list is reinitialised
* @list goes to the end (at head->prev)
*/
static inline void list_splice_tail_init(struct list_head *list, struct list_head *head)
static inline void list_splice_tail_init(struct list_head *list, struct list_head *head) __THROW
{
if (!list_empty(list)) {
__list_splice_tail(list, head);


+ 15
- 5
source/utils/CarlaLibCounter.hpp View File

@@ -1,6 +1,6 @@
/*
* Carla library counter
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -27,12 +27,22 @@
class LibCounter
{
public:
LibCounter() {}
LibCounter() noexcept {}

void* open(const char* const filename)
void* open(const char* const filename) noexcept
{
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);

// try duplicating filename first, it can throw
const char* dfilename = nullptr;

try {
dfilename = carla_strdup(filename);
}
catch(...) {
return nullptr;
}

const CarlaMutexLocker sl(fMutex);

for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next())
@@ -55,7 +65,7 @@ public:

Lib lib;
lib.lib = libPtr;
lib.filename = carla_strdup(filename);
lib.filename = dfilename;
lib.count = 1;

fLibs.append(lib);
@@ -63,7 +73,7 @@ public:
return libPtr;
}

bool close(void* const libPtr)
bool close(void* const libPtr) noexcept
{
CARLA_SAFE_ASSERT_RETURN(libPtr != nullptr, false);



+ 52
- 22
source/utils/LinkedList.hpp View File

@@ -46,6 +46,8 @@ typedef struct list_head k_list_head;
// Abstract Linked List class
// _allocate() and _deallocate are virtual calls provided by subclasses

// NOTE: classes are allowed to throw on creation, but NOT on deletion!

template<typename T>
class AbstractLinkedList
{
@@ -55,7 +57,7 @@ protected:
k_list_head siblings;
};

AbstractLinkedList()
AbstractLinkedList() noexcept
: fDataSize(sizeof(Data)),
fCount(0)
{
@@ -63,7 +65,7 @@ protected:
}

public:
virtual ~AbstractLinkedList()
virtual ~AbstractLinkedList() noexcept
{
CARLA_SAFE_ASSERT(fCount == 0);
}
@@ -113,7 +115,7 @@ public:
return Itenerator(&fQueue);
}

void clear()
void clear() noexcept
{
if (fCount != 0)
{
@@ -143,11 +145,18 @@ public:
return (fCount == 0);
}

bool append(const T& value)
bool append(const T& value) noexcept
{
if (Data* const data = _allocate())
{
new(data)Data();
try {
new(data)Data();
}
catch(...) {
_deallocate(data);
return false;
}

data->value = value;
list_add_tail(&data->siblings, &fQueue);
++fCount;
@@ -157,11 +166,18 @@ public:
return false;
}

bool appendAt(const T& value, const Itenerator& it)
bool appendAt(const T& value, const Itenerator& it) noexcept
{
if (Data* const data = _allocate())
{
new(data)Data();
try {
new(data)Data();
}
catch(...) {
_deallocate(data);
return false;
}

data->value = value;
list_add_tail(&data->siblings, it.fEntry->next);
++fCount;
@@ -171,11 +187,18 @@ public:
return false;
}

bool insert(const T& value)
bool insert(const T& value) noexcept
{
if (Data* const data = _allocate())
{
new(data)Data();
try {
new(data)Data();
}
catch(...) {
_deallocate(data);
return false;
}

data->value = value;
list_add(&data->siblings, &fQueue);
++fCount;
@@ -185,11 +208,18 @@ public:
return false;
}

bool insertAt(const T& value, const Itenerator& it)
bool insertAt(const T& value, const Itenerator& it) noexcept
{
if (Data* const data = _allocate())
{
new(data)Data();
try {
new(data)Data();
}
catch(...) {
_deallocate(data);
return false;
}

data->value = value;
list_add(&data->siblings, it.fEntry->prev);
++fCount;
@@ -225,7 +255,7 @@ public:
return fRetValue;
}

T& getAt(const size_t index, const bool removeObj)
T& getAt(const size_t index, const bool removeObj) noexcept
{
if (fCount == 0 || index >= fCount)
return fRetValue;
@@ -263,17 +293,17 @@ public:
return fRetValue;
}

T& getFirst(const bool removeObj = false)
T& getFirst(const bool removeObj = false) noexcept
{
return _getFirstOrLast(true, removeObj);
}

T& getLast(const bool removeObj = false)
T& getLast(const bool removeObj = false) noexcept
{
return _getFirstOrLast(false, removeObj);
}

void remove(Itenerator& it)
void remove(Itenerator& it) noexcept
{
CARLA_SAFE_ASSERT_RETURN(it.fEntry != nullptr,);

@@ -286,7 +316,7 @@ public:
_deallocate(it.fData);
}

bool removeOne(const T& value)
bool removeOne(const T& value) noexcept
{
Data* data = nullptr;
k_list_head* entry;
@@ -312,7 +342,7 @@ public:
return (data != nullptr);
}

void removeAll(const T& value)
void removeAll(const T& value) noexcept
{
Data* data;
k_list_head* entry;
@@ -370,8 +400,8 @@ protected:
size_t fCount;
k_list_head fQueue;

virtual Data* _allocate() = 0;
virtual void _deallocate(Data*& dataPtr) = 0;
virtual Data* _allocate() noexcept = 0;
virtual void _deallocate(Data*& dataPtr) noexcept = 0;

private:
mutable T fRetValue;
@@ -382,7 +412,7 @@ private:
INIT_LIST_HEAD(&fQueue);
}

T& _getFirstOrLast(const bool first, const bool removeObj)
T& _getFirstOrLast(const bool first, const bool removeObj) noexcept
{
if (fCount == 0)
return fRetValue;
@@ -421,12 +451,12 @@ public:
LinkedList() {}

private:
typename AbstractLinkedList<T>::Data* _allocate() override
typename AbstractLinkedList<T>::Data* _allocate() noexcept override
{
return (typename AbstractLinkedList<T>::Data*)std::malloc(this->fDataSize);
}

void _deallocate(typename AbstractLinkedList<T>::Data*& dataPtr) override
void _deallocate(typename AbstractLinkedList<T>::Data*& dataPtr) noexcept override
{
CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,);



+ 38
- 16
source/utils/RtLinkedList.hpp View File

@@ -37,14 +37,14 @@ public:
class Pool
{
public:
Pool(const size_t minPreallocated, const size_t maxPreallocated)
Pool(const size_t minPreallocated, const size_t maxPreallocated) noexcept
: fHandle(nullptr),
fDataSize(sizeof(typename AbstractLinkedList<T>::Data))
{
resize(minPreallocated, maxPreallocated);
}

~Pool()
~Pool() noexcept
{
if (fHandle != nullptr)
{
@@ -53,22 +53,22 @@ public:
}
}

void* allocate_atomic() const
void* allocate_atomic() const noexcept
{
return rtsafe_memory_pool_allocate_atomic(fHandle);
}

void* allocate_sleepy() const
void* allocate_sleepy() const noexcept
{
return rtsafe_memory_pool_allocate_sleepy(fHandle);
}

void deallocate(void* const dataPtr) const
void deallocate(void* const dataPtr) const noexcept
{
rtsafe_memory_pool_deallocate(fHandle, dataPtr);
}

void resize(const size_t minPreallocated, const size_t maxPreallocated)
void resize(const size_t minPreallocated, const size_t maxPreallocated) noexcept
{
if (fHandle != nullptr)
{
@@ -101,43 +101,65 @@ public:
RtLinkedList(Pool& memPool)
: fMemPool(memPool) {}

void append_sleepy(const T& value)
bool append_sleepy(const T& value) noexcept
{
if (typename AbstractLinkedList<T>::Data* const data = _allocate_sleepy())
{
new(data)typename AbstractLinkedList<T>::Data();
try {
new(data)typename AbstractLinkedList<T>::Data();
}
catch(...) {
_deallocate(data);
return false;
}

data->value = value;
list_add_tail(&data->siblings, &this->fQueue);
++(this->fCount);

return true;
}

return false;
}

void insert_sleepy(const T& value)
bool insert_sleepy(const T& value) noexcept
{
if (typename AbstractLinkedList<T>::Data* const data = _allocate_sleepy())
{
new(data)typename AbstractLinkedList<T>::Data();
try {
new(data)typename AbstractLinkedList<T>::Data();
}
catch(...) {
_deallocate(data);
return false;
}

data->value = value;
list_add(&data->siblings, &this->fQueue);
++(this->fCount);

return true;
}

return false;
}

void resize(const size_t minPreallocated, const size_t maxPreallocated)
void resize(const size_t minPreallocated, const size_t maxPreallocated) noexcept
{
this->clear();

fMemPool.resize(minPreallocated, maxPreallocated);
}

void spliceAppend(RtLinkedList& list, const bool init = true)
void spliceAppend(RtLinkedList& list, const bool init = true) noexcept
{
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,);

AbstractLinkedList<T>::spliceAppend(list, init);
}

void spliceInsert(RtLinkedList& list, const bool init = true)
void spliceInsert(RtLinkedList& list, const bool init = true) noexcept
{
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,);

@@ -147,17 +169,17 @@ public:
private:
Pool& fMemPool;

typename AbstractLinkedList<T>::Data* _allocate() override
typename AbstractLinkedList<T>::Data* _allocate() noexcept override
{
return (typename AbstractLinkedList<T>::Data*)fMemPool.allocate_atomic();
}

typename AbstractLinkedList<T>::Data* _allocate_sleepy()
typename AbstractLinkedList<T>::Data* _allocate_sleepy() noexcept
{
return (typename AbstractLinkedList<T>::Data*)fMemPool.allocate_sleepy();
}

void _deallocate(typename AbstractLinkedList<T>::Data*& dataPtr) override
void _deallocate(typename AbstractLinkedList<T>::Data*& dataPtr) noexcept override
{
CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,);



Loading…
Cancel
Save