From e7b2f7ee286350bc3bb56b44ed98e4d8bf49af82 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 13 Dec 2016 20:53:58 -0500 Subject: Fix real-time issues with buffer allocation --- src/server/BufferFactory.cpp | 56 +++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'src/server/BufferFactory.cpp') diff --git a/src/server/BufferFactory.cpp b/src/server/BufferFactory.cpp index 749e83d0..2fa98b67 100644 --- a/src/server/BufferFactory.cpp +++ b/src/server/BufferFactory.cpp @@ -100,37 +100,51 @@ BufferFactory::default_size(LV2_URID type) const } } +Buffer* +BufferFactory::try_get_buffer(LV2_URID type) +{ + std::atomic& head_ptr = free_list(type); + Buffer* head = NULL; + Buffer* next; + do { + head = head_ptr.load(); + if (!head) { + break; + } + next = head->_next; + } while (!head_ptr.compare_exchange_weak(head, next)); + + return head; +} + BufferRef BufferFactory::get_buffer(LV2_URID type, LV2_URID value_type, - uint32_t capacity, - bool real_time, - bool force_create) + uint32_t capacity) { - std::atomic& head_ptr = free_list(type); - Buffer* try_head = NULL; - - if (!force_create) { - Buffer* next; - do { - try_head = head_ptr.load(); - if (!try_head) - break; - next = try_head->_next; - } while (!head_ptr.compare_exchange_weak(try_head, next)); + Buffer* try_head = try_get_buffer(type); + if (!try_head) { + return create(type, value_type, capacity); } + try_head->_next = NULL; + try_head->set_type(&BufferFactory::get_buffer, type, value_type); + return BufferRef(try_head); +} + +BufferRef +BufferFactory::claim_buffer(LV2_URID type, + LV2_URID value_type, + uint32_t capacity) +{ + Buffer* try_head = try_get_buffer(type); if (!try_head) { - if (!real_time) { - return create(type, value_type, capacity); - } else { - _engine.world()->log().error("Failed to obtain buffer"); - return BufferRef(); - } + _engine.world()->log().rt_error("Failed to obtain buffer"); + return BufferRef(); } try_head->_next = NULL; - try_head->set_type(type, value_type); + try_head->set_type(&BufferFactory::claim_buffer, type, value_type); return BufferRef(try_head); } -- cgit v1.2.1