From 02244e31d57708a3d6169ebd1b6bbe43f4c4fdb2 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 7 Jan 2014 10:26:16 +0000 Subject: [PATCH] Rename list to LinkedList, fix const issues --- .gitignore | 3 +- source/modules/rtmempool/list.h | 4 +- source/tests/Makefile | 8 +- source/tests/RtList.cpp | 195 ------------------ source/utils/{List.hpp => LinkedList.hpp} | 105 +++------- source/utils/{RtList.hpp => RtLinkedList.hpp} | 50 +++-- 6 files changed, 62 insertions(+), 303 deletions(-) delete mode 100644 source/tests/RtList.cpp rename source/utils/{List.hpp => LinkedList.hpp} (79%) rename source/utils/{RtList.hpp => RtLinkedList.hpp} (72%) diff --git a/.gitignore b/.gitignore index 5ca7fd8b7..6c7bbfdce 100644 --- a/.gitignore +++ b/.gitignore @@ -75,7 +75,8 @@ source/tests/CarlaString source/tests/DGL1 source/tests/DGL2 source/tests/Print -source/tests/RtList +source/tests/RtLinkedList +source/tests/RtLinkedListGnu source/tests/Utils source/tests/Widgets diff --git a/source/modules/rtmempool/list.h b/source/modules/rtmempool/list.h index 27159e1fe..b842b2548 100644 --- a/source/modules/rtmempool/list.h +++ b/source/modules/rtmempool/list.h @@ -50,7 +50,7 @@ * */ #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type, member) );}) #define container_of_const(ptr, type, member) ({ \ @@ -304,7 +304,7 @@ static inline void list_splice_tail_init(struct list_head *list, struct list_hea * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ -#if defined(__GNUC__) && ! (defined(BUILD_ANSI_TEST) || defined(QTCREATOR_TEST)) +#if defined(__GNUC__) && ! defined(__STRICT_ANSI__) # define list_entry(ptr, type, member) \ container_of(ptr, type, member) # define list_entry_const(ptr, type, member) \ diff --git a/source/tests/Makefile b/source/tests/Makefile index b3efc1dc3..0a1db4079 100644 --- a/source/tests/Makefile +++ b/source/tests/Makefile @@ -75,9 +75,13 @@ Print: Print.cpp $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -o $@ # valgrind ./Print -RtList: RtList.cpp ../utils/RtList.hpp ../modules/rtmempool.a +RtLinkedList: RtLinkedList.cpp ../utils/LinkedList.hpp ../utils/RtLinkedList.hpp ../modules/rtmempool.a $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -lpthread -o $@ -# valgrind ./RtList + valgrind ./RtLinkedList + +RtLinkedListGnu: RtLinkedList.cpp ../utils/LinkedList.hpp ../utils/RtLinkedList.hpp ../modules/rtmempool.a + $(CXX) $^ $(BUILD_CXX_FLAGS) -std=gnu++11 $(LINK_FLAGS) -lpthread -o $@ + valgrind ./RtLinkedListGnu Utils: Utils.cpp $(CXX) $^ $(BUILD_CXX_FLAGS) $(ANSI_CXX_FLAGS) -std=c++11 -Wzero-as-null-pointer-constant $(LINK_FLAGS) -ldl -lpthread -o $@ diff --git a/source/tests/RtList.cpp b/source/tests/RtList.cpp deleted file mode 100644 index 385661e7a..000000000 --- a/source/tests/RtList.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Carla Tests - * Copyright (C) 2013 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "RtList.hpp" - -#include "CarlaString.hpp" -#include "CarlaMutex.hpp" - -const unsigned short MIN_RT_EVENTS = 5; -const unsigned short MAX_RT_EVENTS = 10; - -struct MyData { - CarlaString str; - int idStr; - - MyData() - : idStr(-1) {} - - MyData(int id) - : str(id), - idStr(id) {} -}; - -struct PostRtEvents { - CarlaMutex mutex; - RtList::Pool dataPool; - RtList data; - RtList dataPendingRT; - - PostRtEvents() - : dataPool(MIN_RT_EVENTS, MAX_RT_EVENTS), - data(dataPool), - dataPendingRT(dataPool) {} - - ~PostRtEvents() - { - clear(); - } - - void appendRT(const MyData& event) - { - dataPendingRT.append(event); - } - - void clear() - { - mutex.lock(); - data.clear(); - dataPendingRT.clear(); - mutex.unlock(); - } - - void trySplice() - { - if (mutex.tryLock()) - { - dataPendingRT.spliceAppend(data); - mutex.unlock(); - } - } - -} postRtEvents; - -void run5Tests() -{ - unsigned short k = 0; - MyData allMyData[MAX_RT_EVENTS]; - - // Make a safe copy of events while clearing them - postRtEvents.mutex.lock(); - - while (! postRtEvents.data.isEmpty()) - { - const MyData& my(postRtEvents.data.getFirst(true)); - allMyData[k++] = my; - } - - postRtEvents.mutex.unlock(); - - printf("Post-Rt Event Count: %i\n", k); - assert(k == 5); - - // data should be empty now - assert(postRtEvents.data.count() == 0); - assert(postRtEvents.data.isEmpty()); - assert(postRtEvents.dataPendingRT.count() == 0); - assert(postRtEvents.dataPendingRT.isEmpty()); - - // Handle events now - for (unsigned short i=0; i < k; ++i) - { - const MyData& my(allMyData[i]); - - printf("Got data: %i %s\n", my.idStr, (const char*)my.str); - } -} - -int main() -{ - MyData m1(1); - MyData m2(2); - MyData m3(3); - MyData m4(4); - MyData m5(5); - - // start - assert(postRtEvents.data.count() == 0); - assert(postRtEvents.data.isEmpty()); - assert(postRtEvents.dataPendingRT.count() == 0); - assert(postRtEvents.dataPendingRT.isEmpty()); - - // single append - postRtEvents.appendRT(m1); - postRtEvents.trySplice(); - assert(postRtEvents.data.count() == 1); - assert(postRtEvents.dataPendingRT.count() == 0); - - // +3 appends - postRtEvents.appendRT(m2); - postRtEvents.appendRT(m4); - postRtEvents.appendRT(m3); - assert(postRtEvents.data.count() == 1); - assert(postRtEvents.dataPendingRT.count() == 3); - postRtEvents.trySplice(); - assert(postRtEvents.data.count() == 4); - assert(postRtEvents.dataPendingRT.count() == 0); - - for (RtList::Itenerator it = postRtEvents.data.begin(); it.valid(); it.next()) - { - MyData& my(*it); - - printf("FOR DATA!!!: %i %s\n", my.idStr, (const char*)my.str); - - if (my.idStr == 1) - { - // +1 append at - postRtEvents.dataPendingRT.insertAt(m5, it); - assert(postRtEvents.data.count() == 4); - assert(postRtEvents.dataPendingRT.count() == 1); - postRtEvents.trySplice(); - assert(postRtEvents.data.count() == 5); - assert(postRtEvents.dataPendingRT.count() == 0); - } - } - - run5Tests(); - - // reset - postRtEvents.clear(); - assert(postRtEvents.data.count() == 0); - assert(postRtEvents.data.isEmpty()); - assert(postRtEvents.dataPendingRT.count() == 0); - assert(postRtEvents.dataPendingRT.isEmpty()); - - // test non-rt - const unsigned int CARLA_EVENT_DATA_ATOM = 0x01; - const unsigned int CARLA_EVENT_DATA_MIDI_LL = 0x04; - - NonRtList evIns, evOuts; - evIns.append(CARLA_EVENT_DATA_ATOM); - evOuts.append(CARLA_EVENT_DATA_ATOM); - evOuts.append(CARLA_EVENT_DATA_MIDI_LL); - - if (evIns.count() > 0) - { - for (uint32_t j=0, count=evIns.count(); j < count; ++j) - { - const uint32_t& type(evIns.getAt(j)); - - if (type == CARLA_EVENT_DATA_ATOM) - pass(); - else if (type == CARLA_EVENT_DATA_MIDI_LL) - pass(); - } - } - - evIns.clear(); - evOuts.clear(); - - return 0; -} diff --git a/source/utils/List.hpp b/source/utils/LinkedList.hpp similarity index 79% rename from source/utils/List.hpp rename to source/utils/LinkedList.hpp index c390bd2db..ee0b6f5f8 100644 --- a/source/utils/List.hpp +++ b/source/utils/LinkedList.hpp @@ -1,6 +1,6 @@ /* * High-level, templated, C++ doubly-linked list - * Copyright (C) 2013 Filipe Coelho + * Copyright (C) 2013-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,8 +15,8 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#ifndef LIST_HPP_INCLUDED -#define LIST_HPP_INCLUDED +#ifndef LINKED_LIST_HPP_INCLUDED +#define LINKED_LIST_HPP_INCLUDED #include "CarlaUtils.hpp" @@ -28,26 +28,26 @@ extern "C" { // Declare non copyable and prevent heap allocation #ifdef CARLA_PROPER_CPP11_SUPPORT -# define LIST_DECLARATIONS(ClassName) \ +# define LINKED_LIST_DECLARATIONS(ClassName) \ ClassName(ClassName&) = delete; \ ClassName(const ClassName&) = delete; \ ClassName& operator=(const ClassName&) = delete; \ static void* operator new(size_t) = delete; #else -# define LIST_DECLARATIONS(ClassName) \ - ClassName(ClassName&); \ - ClassName(const ClassName&); \ +# define LINKED_LIST_DECLARATIONS(ClassName) \ + ClassName(ClassName&); \ + ClassName(const ClassName&); \ ClassName& operator=(const ClassName&); #endif typedef struct list_head k_list_head; // ----------------------------------------------------------------------- -// Abstract List class +// Abstract Linked List class // _allocate() and _deallocate are virtual calls provided by subclasses template -class AbstractList +class AbstractLinkedList { protected: struct Data { @@ -55,26 +55,26 @@ protected: k_list_head siblings; }; - AbstractList() + AbstractLinkedList() : fDataSize(sizeof(Data)), fCount(0) { _init(); } - virtual ~AbstractList() +public: + virtual ~AbstractLinkedList() { CARLA_ASSERT(fCount == 0); } -public: class Itenerator { public: Itenerator(const k_list_head* queue) - : fEntry(queue->next), + : fData(nullptr), + fEntry(queue->next), fEntry2(fEntry->next), - fQueue(queue), - fData(nullptr) + fQueue(queue) { CARLA_ASSERT(fEntry != nullptr); CARLA_ASSERT(fEntry2 != nullptr); @@ -99,31 +99,13 @@ public: return fData->value; } - const T& getConstValue() - { - fConstData = list_entry_const(fEntry, Data, siblings); - CARLA_ASSERT(fConstData != nullptr); - return fConstData->value; - } - -#if 0 - T& operator*() const - { - return getValue(); - } -#endif - private: + Data* fData; k_list_head* fEntry; k_list_head* fEntry2; const k_list_head* const fQueue; - union { - Data* fData; - const Data* fConstData; - }; - - friend class AbstractList; + friend class AbstractLinkedList; }; Itenerator begin() const @@ -151,35 +133,6 @@ public: _init(); } - // temporary fix for some const issue in midi-base.hpp - void clear_const() - { - if (fCount != 0) - { - k_list_head* entry; - k_list_head* entry2; - - list_for_each_safe(entry, entry2, &fQueue) - { - if (const Data* data = list_entry_const(entry, Data, siblings)) - { - data->~Data(); - - union CData { - const Data* cdata; - Data* data; - }; - - CData d; - d.cdata = data; - _deallocate(d.data); - } - } - } - - _init(); - } - size_t count() const noexcept { return fCount; @@ -356,7 +309,7 @@ public: } } - void spliceAppend(AbstractList& list, const bool init = true) + void spliceAppend(AbstractLinkedList& list, const bool init = true) { if (init) { @@ -371,7 +324,7 @@ public: } } - void spliceInsert(AbstractList& list, const bool init = true) + void spliceInsert(AbstractLinkedList& list, const bool init = true) { if (init) { @@ -429,27 +382,25 @@ private: return fRetValue; } - LIST_DECLARATIONS(AbstractList) + LINKED_LIST_DECLARATIONS(AbstractLinkedList) }; // ----------------------------------------------------------------------- -// List +// LinkedList template -class List : public AbstractList +class LinkedList : public AbstractLinkedList { public: - List() - { - } + LinkedList() {} private: - typename AbstractList::Data* _allocate() override + typename AbstractLinkedList::Data* _allocate() override { - return (typename AbstractList::Data*)std::malloc(this->fDataSize); + return (typename AbstractLinkedList::Data*)std::malloc(this->fDataSize); } - void _deallocate(typename AbstractList::Data*& dataPtr) override + void _deallocate(typename AbstractLinkedList::Data*& dataPtr) override { CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); @@ -457,9 +408,9 @@ private: dataPtr = nullptr; } - LIST_DECLARATIONS(List) + LINKED_LIST_DECLARATIONS(LinkedList) }; // ----------------------------------------------------------------------- -#endif // LIST_HPP_INCLUDED +#endif // LINKED_LIST_HPP_INCLUDED diff --git a/source/utils/RtList.hpp b/source/utils/RtLinkedList.hpp similarity index 72% rename from source/utils/RtList.hpp rename to source/utils/RtLinkedList.hpp index 720ba01f4..d7cfe3b10 100644 --- a/source/utils/RtList.hpp +++ b/source/utils/RtLinkedList.hpp @@ -15,20 +15,20 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#ifndef RT_LIST_HPP_INCLUDED -#define RT_LIST_HPP_INCLUDED +#ifndef RT_LINKED_LIST_HPP_INCLUDED +#define RT_LINKED_LIST_HPP_INCLUDED -#include "List.hpp" +#include "LinkedList.hpp" extern "C" { #include "rtmempool/rtmempool.h" } // ----------------------------------------------------------------------- -// Realtime safe list +// Realtime safe linkedlist template -class RtList : public AbstractList +class RtLinkedList : public AbstractLinkedList { public: // ------------------------------------------------------------------- @@ -39,7 +39,7 @@ public: public: Pool(const size_t minPreallocated, const size_t maxPreallocated) : fHandle(nullptr), - fDataSize(sizeof(typename AbstractList::Data)) + fDataSize(sizeof(typename AbstractLinkedList::Data)) { resize(minPreallocated, maxPreallocated); } @@ -96,18 +96,16 @@ public: }; // ------------------------------------------------------------------- - // Now the actual rt-list code + // Now the actual rt-linkedlist code - RtList(Pool& memPool) - : fMemPool(memPool) - { - } + RtLinkedList(Pool& memPool) + : fMemPool(memPool) {} void append_sleepy(const T& value) { - if (typename AbstractList::Data* const data = _allocate_sleepy()) + if (typename AbstractLinkedList::Data* const data = _allocate_sleepy()) { - new(data)typename AbstractList::Data(); + new(data)typename AbstractLinkedList::Data(); data->value = value; list_add_tail(&data->siblings, &this->fQueue); ++(this->fCount); @@ -116,9 +114,9 @@ public: void insert_sleepy(const T& value) { - if (typename AbstractList::Data* const data = _allocate_sleepy()) + if (typename AbstractLinkedList::Data* const data = _allocate_sleepy()) { - new(data)typename AbstractList::Data(); + new(data)typename AbstractLinkedList::Data(); data->value = value; list_add(&data->siblings, &this->fQueue); ++(this->fCount); @@ -132,34 +130,34 @@ public: fMemPool.resize(minPreallocated, maxPreallocated); } - void spliceAppend(RtList& list, const bool init = true) + void spliceAppend(RtLinkedList& list, const bool init = true) { CARLA_ASSERT(fMemPool == list.fMemPool); - AbstractList::spliceAppend(list, init); + AbstractLinkedList::spliceAppend(list, init); } - void spliceInsert(RtList& list, const bool init = true) + void spliceInsert(RtLinkedList& list, const bool init = true) { CARLA_ASSERT(fMemPool == list.fMemPool); - AbstractList::spliceInsert(list, init); + AbstractLinkedList::spliceInsert(list, init); } private: Pool& fMemPool; - typename AbstractList::Data* _allocate() override + typename AbstractLinkedList::Data* _allocate() override { - return (typename AbstractList::Data*)fMemPool.allocate_atomic(); + return (typename AbstractLinkedList::Data*)fMemPool.allocate_atomic(); } - typename AbstractList::Data* _allocate_sleepy() + typename AbstractLinkedList::Data* _allocate_sleepy() { - return (typename AbstractList::Data*)fMemPool.allocate_sleepy(); + return (typename AbstractLinkedList::Data*)fMemPool.allocate_sleepy(); } - void _deallocate(typename AbstractList::Data*& dataPtr) override + void _deallocate(typename AbstractLinkedList::Data*& dataPtr) override { CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); @@ -167,9 +165,9 @@ private: dataPtr = nullptr; } - LIST_DECLARATIONS(RtList) + LINKED_LIST_DECLARATIONS(RtLinkedList) }; // ----------------------------------------------------------------------- -#endif // RT_LIST_HPP_INCLUDED +#endif // RT_LINKED_LIST_HPP_INCLUDED