diff options
-rw-r--r-- | Kodi.xcodeproj/project.pbxproj | 10 | ||||
-rw-r--r-- | project/VS2010Express/XbmcThreads.vcxproj | 2 | ||||
-rw-r--r-- | project/VS2010Express/XbmcThreads.vcxproj.filters | 2 | ||||
-rw-r--r-- | xbmc/threads/LockFree.cpp | 279 | ||||
-rw-r--r-- | xbmc/threads/LockFree.h | 124 | ||||
-rw-r--r-- | xbmc/threads/Makefile | 1 |
6 files changed, 0 insertions, 418 deletions
diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 21170206de..639a6a4cad 100644 --- a/Kodi.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -732,7 +732,6 @@ 7CF80DCB19710DC2003B2B34 /* KeyboardLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CF80DC719710DC2003B2B34 /* KeyboardLayout.cpp */; }; 815EE6350E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 815EE6330E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp */; }; 820023DB171A28A300667D1C /* OSXTextInputResponder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 820023DA171A28A300667D1C /* OSXTextInputResponder.mm */; }; - 83A72B970FBC8E3B00171871 /* LockFree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B950FBC8E3B00171871 /* LockFree.cpp */; settings = {COMPILER_FLAGS = "-O0"; }; }; 83E0B2490F7C95FF0091643F /* Atomics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83E0B2480F7C95FF0091643F /* Atomics.cpp */; }; 880DBE4E0DC223FF00E26B71 /* MediaSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 880DBE4B0DC223FF00E26B71 /* MediaSource.cpp */; }; 880DBE550DC224A100E26B71 /* MusicFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 880DBE530DC224A100E26B71 /* MusicFileDirectory.cpp */; }; @@ -1743,7 +1742,6 @@ DFF0F3B317528350002DA3A4 /* Implementation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38F4E56C13CCCB3B00664821 /* Implementation.cpp */; }; DFF0F3B417528350002DA3A4 /* Atomics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83E0B2480F7C95FF0091643F /* Atomics.cpp */; }; DFF0F3B517528350002DA3A4 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E350D25F9FD00618676 /* Event.cpp */; }; - DFF0F3B617528350002DA3A4 /* LockFree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B950FBC8E3B00171871 /* LockFree.cpp */; }; DFF0F3B717528350002DA3A4 /* SystemClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3802709813D5A653009493DD /* SystemClock.cpp */; }; DFF0F3B817528350002DA3A4 /* Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E850D25F9FD00618676 /* Thread.cpp */; }; DFF0F3B917528350002DA3A4 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD928F116384B6800709DAE /* Timer.cpp */; }; @@ -2910,7 +2908,6 @@ E4991437174E604700741B6D /* Implementation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38F4E56C13CCCB3B00664821 /* Implementation.cpp */; }; E4991438174E604700741B6D /* Atomics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83E0B2480F7C95FF0091643F /* Atomics.cpp */; }; E4991439174E604700741B6D /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E350D25F9FD00618676 /* Event.cpp */; }; - E499143A174E604700741B6D /* LockFree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B950FBC8E3B00171871 /* LockFree.cpp */; }; E499143B174E604700741B6D /* SystemClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3802709813D5A653009493DD /* SystemClock.cpp */; }; E499143C174E604700741B6D /* Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E850D25F9FD00618676 /* Thread.cpp */; }; E499143D174E604700741B6D /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD928F116384B6800709DAE /* Timer.cpp */; }; @@ -4242,8 +4239,6 @@ 820023D9171A28A300667D1C /* OSXTextInputResponder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSXTextInputResponder.h; sourceTree = "<group>"; }; 820023DA171A28A300667D1C /* OSXTextInputResponder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSXTextInputResponder.mm; sourceTree = "<group>"; }; 82F6F0EA16F269BB0081CC3C /* Buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Buffer.h; path = commons/Buffer.h; sourceTree = "<group>"; }; - 83A72B950FBC8E3B00171871 /* LockFree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockFree.cpp; sourceTree = "<group>"; }; - 83A72B960FBC8E3B00171871 /* LockFree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LockFree.h; sourceTree = "<group>"; }; 83E0B2470F7C95FF0091643F /* Atomics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atomics.h; sourceTree = "<group>"; }; 83E0B2480F7C95FF0091643F /* Atomics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atomics.cpp; sourceTree = "<group>"; }; 880DBE490DC223FF00E26B71 /* Album.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Album.h; sourceTree = "<group>"; }; @@ -6811,8 +6806,6 @@ E38E1E360D25F9FD00618676 /* Event.h */, 38F4E55E13CCCB3B00664821 /* Helpers.h */, 38F4E55F13CCCB3B00664821 /* Lockables.h */, - 83A72B950FBC8E3B00171871 /* LockFree.cpp */, - 83A72B960FBC8E3B00171871 /* LockFree.h */, E38E1E7A0D25F9FD00618676 /* SharedSection.h */, E38E1E7C0D25F9FD00618676 /* SingleLock.h */, 3802709813D5A653009493DD /* SystemClock.cpp */, @@ -10670,7 +10663,6 @@ F5AACA680FB3DE2D00DBB77C /* GUIDialogSelect.cpp in Sources */, F5AACA970FB3E2B800DBB77C /* GUIDialogSlider.cpp in Sources */, F59876C00FBA351D008EF4FB /* VideoReferenceClock.cpp in Sources */, - 83A72B970FBC8E3B00171871 /* LockFree.cpp in Sources */, F5987F050FBDF274008EF4FB /* DPMSSupport.cpp in Sources */, F5987FDB0FBE2DFD008EF4FB /* PAPlayer.cpp in Sources */, F548786D0FE060FF00E506FD /* DVDSubtitleParserMPL2.cpp in Sources */, @@ -12031,7 +12023,6 @@ DFF0F3B417528350002DA3A4 /* Atomics.cpp in Sources */, DFF0F3B517528350002DA3A4 /* Event.cpp in Sources */, DF29BCFC1B5D911800904347 /* GUIViewStateEventLog.cpp in Sources */, - DFF0F3B617528350002DA3A4 /* LockFree.cpp in Sources */, DFF0F3B717528350002DA3A4 /* SystemClock.cpp in Sources */, DFF0F3B817528350002DA3A4 /* Thread.cpp in Sources */, DFF0F3B917528350002DA3A4 /* Timer.cpp in Sources */, @@ -13092,7 +13083,6 @@ E4991437174E604700741B6D /* Implementation.cpp in Sources */, E4991438174E604700741B6D /* Atomics.cpp in Sources */, E4991439174E604700741B6D /* Event.cpp in Sources */, - E499143A174E604700741B6D /* LockFree.cpp in Sources */, E499143B174E604700741B6D /* SystemClock.cpp in Sources */, E499143C174E604700741B6D /* Thread.cpp in Sources */, E499143D174E604700741B6D /* Timer.cpp in Sources */, diff --git a/project/VS2010Express/XbmcThreads.vcxproj b/project/VS2010Express/XbmcThreads.vcxproj index 8ce0f502fe..a5cecd8f6e 100644 --- a/project/VS2010Express/XbmcThreads.vcxproj +++ b/project/VS2010Express/XbmcThreads.vcxproj @@ -13,7 +13,6 @@ <ItemGroup> <ClCompile Include="..\..\xbmc\threads\Atomics.cpp" /> <ClCompile Include="..\..\xbmc\threads\Event.cpp" /> - <ClCompile Include="..\..\xbmc\threads\LockFree.cpp" /> <ClCompile Include="..\..\xbmc\threads\Timer.cpp" /> <ClInclude Include="..\..\xbmc\threads\platform\ThreadImpl.h" /> <ClInclude Include="..\..\xbmc\threads\platform\win\ThreadImpl.cpp" /> @@ -31,7 +30,6 @@ <ClInclude Include="..\..\xbmc\threads\Event.h" /> <ClInclude Include="..\..\xbmc\threads\Helpers.h" /> <ClInclude Include="..\..\xbmc\threads\Lockables.h" /> - <ClInclude Include="..\..\xbmc\threads\LockFree.h" /> <ClInclude Include="..\..\xbmc\threads\platform\Condition.h" /> <ClInclude Include="..\..\xbmc\threads\platform\CriticalSection.h" /> <ClInclude Include="..\..\xbmc\threads\platform\ThreadLocal.h" /> diff --git a/project/VS2010Express/XbmcThreads.vcxproj.filters b/project/VS2010Express/XbmcThreads.vcxproj.filters index ba6170653d..7de0862be9 100644 --- a/project/VS2010Express/XbmcThreads.vcxproj.filters +++ b/project/VS2010Express/XbmcThreads.vcxproj.filters @@ -3,7 +3,6 @@ <ItemGroup> <ClCompile Include="..\..\xbmc\threads\Atomics.cpp" /> <ClCompile Include="..\..\xbmc\threads\Event.cpp" /> - <ClCompile Include="..\..\xbmc\threads\LockFree.cpp" /> <ClCompile Include="..\..\xbmc\threads\Thread.cpp" /> <ClCompile Include="..\..\xbmc\threads\SystemClock.cpp" /> <ClCompile Include="..\..\xbmc\threads\platform\Implementation.cpp"> @@ -21,7 +20,6 @@ <ClInclude Include="..\..\xbmc\threads\Event.h" /> <ClInclude Include="..\..\xbmc\threads\Helpers.h" /> <ClInclude Include="..\..\xbmc\threads\Lockables.h" /> - <ClInclude Include="..\..\xbmc\threads\LockFree.h" /> <ClInclude Include="..\..\xbmc\threads\SharedSection.h" /> <ClInclude Include="..\..\xbmc\threads\SingleLock.h" /> <ClInclude Include="..\..\xbmc\threads\Thread.h" /> diff --git a/xbmc/threads/LockFree.cpp b/xbmc/threads/LockFree.cpp deleted file mode 100644 index d0ae78a6b7..0000000000 --- a/xbmc/threads/LockFree.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * 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, or (at your option) - * 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. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#ifdef __ppc__ -#pragma GCC optimization_level 0 -#endif - -#include "LockFree.h" -#include <stdlib.h> - -/////////////////////////////////////////////////////////////////////////// -// Fast stack implementation -// NOTE: non-locking only on systems that support atomic cas2 operations -/////////////////////////////////////////////////////////////////////////// -void lf_stack_init(lf_stack* pStack) -{ - pStack->top.ptr = NULL; - pStack->count = 0; -} - -void lf_stack_push(lf_stack* pStack, lf_node* pNode) -{ - atomic_ptr top, newTop; - do - { - top = pStack->top; - pNode->next.ptr = top.ptr; // Link in the new node - newTop.ptr = pNode; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - } while(cas((long*)&pStack->top, atomic_ptr_to_long(top), atomic_ptr_to_long(newTop)) != atomic_ptr_to_long(top)); -#else - newTop.version = top.version + 1; - } while(cas2((long long*)&pStack->top, atomic_ptr_to_long_long(top), atomic_ptr_to_long_long(newTop)) != atomic_ptr_to_long_long(top)); -#endif - AtomicIncrement(&pStack->count); -} - -lf_node* lf_stack_pop(lf_stack* pStack) -{ - atomic_ptr top, newTop; - do - { - top = pStack->top; - if (top.ptr == NULL) - return NULL; - newTop.ptr = ((lf_node*)top.ptr)->next.ptr; // Unlink the current top node -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - } while(cas((long*)&pStack->top, atomic_ptr_to_long(top), atomic_ptr_to_long(newTop)) != atomic_ptr_to_long(top)); -#else - newTop.version = top.version + 1; - } while(cas2((long long*)&pStack->top, atomic_ptr_to_long_long(top), atomic_ptr_to_long_long(newTop)) != atomic_ptr_to_long_long(top)); -#endif - AtomicDecrement(&pStack->count); - return (lf_node*)top.ptr; -} - -/////////////////////////////////////////////////////////////////////////// -// Fast heap implementation -// NOTE: non-locking only on systems that support atomic cas2 operations -/////////////////////////////////////////////////////////////////////////// -// TODO: Implement auto-shrink based on chunk reference counts - -// TODO: Read the page size from the OS or allow caller to specify -// Maybe have a minimum number of blocks... -#define MIN_ALLOC 4096 - -void lf_heap_init(lf_heap* pHeap, size_t blockSize, size_t initialSize /*= 0*/) -{ - pHeap->alloc_lock = 0; // Initialize the allocation lock - pHeap->top_chunk = NULL; - - lf_stack_init(&pHeap->free_list); // Initialize the free-list stack - - // Perform a few sanity checks on the parameters - if (blockSize < sizeof(lf_node)) // Make sure we have blocks big enough to store in the free-list - blockSize = sizeof(lf_node); - pHeap->block_size = blockSize; - - if (initialSize < 10 * blockSize) - initialSize = 10 * blockSize; // TODO: This should be more intelligent - - lf_heap_grow(pHeap, initialSize); // Allocate the first chunk -} - -void lf_heap_grow(lf_heap* pHeap, size_t size /*= 0*/) -{ - - long blockSize = pHeap->block_size; // This has already been checked for sanity - if (!size || size < MIN_ALLOC - sizeof(lf_heap_chunk)) // Allocate at least one page from the OS (TODO: Try valloc) - size = MIN_ALLOC - sizeof(lf_heap_chunk); - unsigned int blockCount = size / blockSize; - if (size % blockSize) // maxe sure we have complete blocks - size = blockSize * ++blockCount; - - // Allocate the first chunk from the general heap and link it into the chunk list - long mallocSize = size + sizeof(lf_heap_chunk); - lf_heap_chunk* pChunk = (lf_heap_chunk*) malloc(mallocSize); - if (!pChunk) - return; - pChunk->size = mallocSize; - SPINLOCK_ACQUIRE(pHeap->alloc_lock); // Lock the chunk list. Contention here is VERY unlikely, so use the simplest possible sync mechanism. - pChunk->next = pHeap->top_chunk; - pHeap->top_chunk = pChunk; // Link it into the list - SPINLOCK_RELEASE(pHeap->alloc_lock); // The list is now consistent - - // Add all blocks to the free-list - unsigned char* pBlock = (unsigned char*)pChunk + sizeof(lf_heap_chunk); - for ( unsigned int block = 0; block < blockCount; block++) - { - lf_stack_push(&pHeap->free_list, (lf_node*)pBlock); - pBlock += blockSize; - } -} - -void lf_heap_deinit(lf_heap* pHeap) -{ - // Free all allocated chunks - lf_heap_chunk* pNext; - for(lf_heap_chunk* pChunk = pHeap->top_chunk; pChunk; pChunk = pNext) - { - pNext = pChunk->next; - free(pChunk); - } -} - -void* lf_heap_alloc(lf_heap* pHeap) -{ - void * p = lf_stack_pop(&pHeap->free_list); - if (!p) - { - lf_heap_grow(pHeap, 0); - // TODO: should we just call in recursively? - return lf_stack_pop(&pHeap->free_list); // If growing didn't help, something is wrong (or someone else took them all REALLY fast) - } - return p; -} - -void lf_heap_free(lf_heap* pHeap, void* p) -{ - if (!p) // Allow for NULL to pass safely - return; - lf_stack_push(&pHeap->free_list, (lf_node*)p); // Return the block to the free list -} - -/////////////////////////////////////////////////////////////////////////// -// Lock-free queue -/////////////////////////////////////////////////////////////////////////// -void lf_queue_init(lf_queue* pQueue) -{ - pQueue->len = 0; - lf_heap_init(&pQueue->node_heap, sizeof(lf_queue_node)); // Intialize the node heap - lf_queue_node* pNode = lf_queue_new_node(pQueue); // Create the 'empty' node - pNode->next.ptr = NULL; - pNode->value = (void*)0xdeadf00d; - pQueue->head.ptr = pQueue->tail.ptr = pNode; -} - -void lf_queue_deinit(lf_queue* pQueue) -{ - lf_heap_deinit(&pQueue->node_heap); // Clean up the node heap -} - -// TODO: template-ize -void lf_queue_enqueue(lf_queue* pQueue, void* value) -{ - lf_queue_node* pNode = lf_queue_new_node(pQueue); // Get a container - pNode->value = value; - pNode->next.ptr = NULL; - atomic_ptr tail, next, node; - do - { - tail = pQueue->tail; - next = ((lf_queue_node*)tail.ptr)->next; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - if (atomic_ptr_to_long(tail) == atomic_ptr_to_long(pQueue->tail)) // Check consistency -#else - if (atomic_ptr_to_long_long(tail) == atomic_ptr_to_long_long(pQueue->tail)) // Check consistency -#endif - { - if (next.ptr == NULL) // Was tail pointing to the last node? - { - node.ptr = pNode; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - if (cas((long*)&((lf_queue_node*)tail.ptr)->next, atomic_ptr_to_long(next), atomic_ptr_to_long(node)) == atomic_ptr_to_long(next)) // Try to link node at end -#else - node.version = next.version + 1; - if (cas2((long long*)&((lf_queue_node*)tail.ptr)->next, atomic_ptr_to_long_long(next), atomic_ptr_to_long_long(node)) == atomic_ptr_to_long_long(next)) // Try to link node at end -#endif - break; // enqueue is done. - } - else // tail was lagging, try to help... - { - node.ptr = next.ptr; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - cas((long*)&pQueue->tail, atomic_ptr_to_long(tail), atomic_ptr_to_long(node)); // We don't care if we are successful or not -#else - node.version = tail.version + 1; - cas2((long long*)&pQueue->tail, atomic_ptr_to_long_long(tail), atomic_ptr_to_long_long(node)); // We don't care if we are successful or not -#endif - } - } - } while (true); // Keep trying until the enqueue is done - node.ptr = pNode; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - cas((long*)&pQueue->tail, atomic_ptr_to_long(tail), atomic_ptr_to_long(node)); // Try to swing the tail to the new node -#else - node.version = tail.version + 1; - cas2((long long*)&pQueue->tail, atomic_ptr_to_long_long(tail), atomic_ptr_to_long_long(node)); // Try to swing the tail to the new node -#endif - AtomicIncrement(&pQueue->len); -} - -// TODO: template-ize -void* lf_queue_dequeue(lf_queue* pQueue) -{ - atomic_ptr head, tail, next, node; - void* pVal = NULL; - do - { - head = pQueue->head; - tail = pQueue->tail; - next = ((lf_queue_node*)head.ptr)->next; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - if (atomic_ptr_to_long(head) == atomic_ptr_to_long(pQueue->head)) // Check consistency -#else - if (atomic_ptr_to_long_long(head) == atomic_ptr_to_long_long(pQueue->head)) // Check consistency -#endif - { - if (head.ptr == tail.ptr) // Queue is empty or tail is lagging - { - if (next.ptr == NULL) // Queue is empty - return NULL; - node.ptr = next.ptr; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - cas((long*)&pQueue->tail, atomic_ptr_to_long(tail), atomic_ptr_to_long(node)); // Tail is lagging. Try to advance it. -#else - node.version = tail.version + 1; - cas2((long long*)&pQueue->tail, atomic_ptr_to_long_long(tail), atomic_ptr_to_long_long(node)); // Tail is lagging. Try to advance it. -#endif - } - else // Tail is consistent. No need to deal with it. - { - pVal = ((lf_queue_node*)next.ptr)->value; - node.ptr = next.ptr; -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - if (cas((long*)&pQueue->head, atomic_ptr_to_long(head), atomic_ptr_to_long(node)) == atomic_ptr_to_long(head)) -#else - node.version = head.version + 1; - if (cas2((long long*)&pQueue->head, atomic_ptr_to_long_long(head), atomic_ptr_to_long_long(node)) == atomic_ptr_to_long_long(head)) -#endif - break; // Dequeue is done - } - } - } while (true); // Keep trying until the dequeue is done or the queue empties - lf_queue_free_node(pQueue, head.ptr); - AtomicDecrement(&pQueue->len); - return pVal; -} - -#ifdef __ppc__ -#pragma GCC optimization_level reset -#endif diff --git a/xbmc/threads/LockFree.h b/xbmc/threads/LockFree.h deleted file mode 100644 index d440eaaf02..0000000000 --- a/xbmc/threads/LockFree.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * 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, or (at your option) - * 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. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#ifndef __LOCK_FREE_H__ -#define __LOCK_FREE_H__ - -#include <cstring> -#include "Atomics.h" - -#define SPINLOCK_ACQUIRE(l) while(cas(&l, 0, 1)) {} -#define SPINLOCK_RELEASE(l) l = 0 - -// A unique-valued pointer. Version is incremented with each write. -union atomic_ptr -{ -#if !defined(__ppc__) && !defined(__powerpc__) && !defined(__arm__) - long long d; - struct { - void* ptr; - long version; - }; -#else - long d; - struct { - void* ptr; - }; -#endif -}; - -#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) - #define atomic_ptr_to_long(p) (long) *((long*)&p) -#else - // This is ugly but correct as long as sizeof(void*) == sizeof(long)... - #define atomic_ptr_to_long_long(p) (long long) *((long long*)&p) -#endif - -struct lf_node -{ - atomic_ptr next; -}; - -/////////////////////////////////////////////////////////////////////////// -// Fast Stack -/////////////////////////////////////////////////////////////////////////// - - -struct lf_stack -{ - atomic_ptr top; - long count; -}; - - -void lf_stack_init(lf_stack* pStack); -void lf_stack_push(lf_stack* pStack, lf_node* pNode); -lf_node* lf_stack_pop(lf_stack* pStack); - -/////////////////////////////////////////////////////////////////////////// -// Fast Heap for Fixed-size Blocks -/////////////////////////////////////////////////////////////////////////// -struct lf_heap_chunk -{ - lf_heap_chunk* next; - long size; -}; - -struct lf_heap -{ - lf_stack free_list; - long alloc_lock; - lf_heap_chunk* top_chunk; - long block_size; -}; - - -void lf_heap_init(lf_heap* pHeap, size_t blockSize, size_t initialSize = 0); -void lf_heap_grow(lf_heap* pHeap, size_t size = 0); -void lf_heap_deinit(lf_heap* pHeap); -void* lf_heap_alloc(lf_heap* pHeap); -void lf_heap_free(lf_heap* pHeap, void* p); - -/////////////////////////////////////////////////////////////////////////// -// Lock-free queue -/////////////////////////////////////////////////////////////////////////// -struct lf_queue_node -{ - atomic_ptr next; - void* value; // TODO: Convert to a template -}; - -struct lf_queue -{ - atomic_ptr head; - atomic_ptr tail; - lf_heap node_heap; - long len; -}; - -#define lf_queue_new_node(q) (lf_queue_node*)lf_heap_alloc(&q->node_heap) -#define lf_queue_free_node(q,n) lf_heap_free(&q->node_heap, n) - -void lf_queue_init(lf_queue* pQueue); -void lf_queue_deinit(lf_queue* pQueue); -void lf_queue_enqueue(lf_queue* pQueue, void* pVal); -void* lf_queue_dequeue(lf_queue* pQueue); - -#endif diff --git a/xbmc/threads/Makefile b/xbmc/threads/Makefile index d0bd2951d7..fc2c02d6f1 100644 --- a/xbmc/threads/Makefile +++ b/xbmc/threads/Makefile @@ -1,6 +1,5 @@ SRCS=Atomics.cpp \ Event.cpp \ - LockFree.cpp \ Thread.cpp \ Timer.cpp \ SystemClock.cpp \ |