mirror of
https://github.com/gnustep/libs-performance.git
synced 2025-02-20 18:32:04 +00:00
Add non-blocking FIFO functions/methods
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/performance/trunk@33064 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
6a4b4db806
commit
b5bd053574
3 changed files with 128 additions and 10 deletions
|
@ -1,3 +1,10 @@
|
|||
2011-05-19 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* GNUmakefile: Add FIFO
|
||||
* Performance.h: Add FIFO
|
||||
* GSFIFO.h: Add a FIFO class
|
||||
* GSFIFO.m: Add a FIFO class
|
||||
|
||||
2011-03-08 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* GNUmakefile: Bump version number for next release.
|
||||
|
|
68
GSFIFO.h
68
GSFIFO.h
|
@ -65,11 +65,11 @@
|
|||
@public
|
||||
/* While the following instance variables are nominally public, they are in
|
||||
* fact only intended to be used by the provided inline functions ... you
|
||||
* should not acces them direcdtly in your own code.
|
||||
* should not access them directly in your own code.
|
||||
*/
|
||||
volatile uint64_t _head;
|
||||
volatile uint64_t _tail;
|
||||
id *_items;
|
||||
uint64_t _head;
|
||||
uint64_t _tail;
|
||||
uint32_t _capacity;
|
||||
@private
|
||||
uint16_t granularity;
|
||||
|
@ -81,6 +81,10 @@
|
|||
NSString *name;
|
||||
}
|
||||
|
||||
/** Returns the approximate number of objects in the FIFO.
|
||||
*/
|
||||
- (NSUInteger) count;
|
||||
|
||||
/** Gets the next object from the FIFO, blocking if necessary until an
|
||||
* object is available. Raises an exception if the FIFO is configured
|
||||
* with a timeout and it is exceeded.
|
||||
|
@ -115,14 +119,25 @@
|
|||
* with a timeout and it is exceeded.
|
||||
*/
|
||||
- (void) put: (id)item;
|
||||
|
||||
/** Checks the FIFO and returns the first available object or nil if the
|
||||
* FIFO is empty.
|
||||
*/
|
||||
- (id) tryGet;
|
||||
|
||||
/** Attempts to put an item into the FIFO, returning YES on success or NO
|
||||
* if the FIFO is full.
|
||||
*/
|
||||
- (BOOL) tryPut: (id)item;
|
||||
@end
|
||||
|
||||
/** Function to efficiently get an item from a fast FIFO.<br />
|
||||
* Returns nil if the FIFO is empty.<br />
|
||||
* Warning ... only for use if the FIFO is NOT configured for multiple
|
||||
* consumers.
|
||||
*/
|
||||
static inline id
|
||||
GSGetFastFIFO(GSFIFO *receiver)
|
||||
GSGetFastNonBlockingFIFO(GSFIFO *receiver)
|
||||
{
|
||||
if (receiver->_head > receiver->_tail)
|
||||
{
|
||||
|
@ -132,23 +147,56 @@ GSGetFastFIFO(GSFIFO *receiver)
|
|||
receiver->_tail++;
|
||||
return object;
|
||||
}
|
||||
return [receiver get];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/** Function to efficiently get an item from a fast FIFO, blocking if
|
||||
* necessary until an object is available or the timeout occurs.<br />
|
||||
* Warning ... only for use if the FIFO is NOT configured for multiple
|
||||
* consumers.
|
||||
*/
|
||||
static inline id
|
||||
GSGetFastFIFO(GSFIFO *receiver)
|
||||
{
|
||||
id object = GSGetFastNonBlockingFIFO(receiver);
|
||||
|
||||
if (nil == object)
|
||||
{
|
||||
object = [receiver get];
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
/** Function to efficiently put an item to a fast FIFO.<br />
|
||||
* Returns YES on success, NO on failure (FIFO is full).<br />
|
||||
* Warning ... only for use if the FIFO is NOT configured for multiple
|
||||
* producers.
|
||||
*/
|
||||
static inline BOOL
|
||||
GSPutFastNonBlockingFIFO(GSFIFO *receiver, id item)
|
||||
{
|
||||
if (receiver->_head - receiver->_tail < receiver->_capacity)
|
||||
{
|
||||
receiver->_items[receiver->_head % receiver->_capacity] = item;
|
||||
receiver->_head++;
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
/** Function to efficiently put an item to a fast FIFO, blocking if
|
||||
* necessary untile there is space in the FIFO or until the timeout
|
||||
* occurs.<br />
|
||||
* Warning ... only for use if the FIFO is NOT configured for multiple
|
||||
* producers.
|
||||
*/
|
||||
static inline void
|
||||
GSPutFastFIFO(GSFIFO *receiver, id item)
|
||||
{
|
||||
if (receiver->_head - receiver->_tail < receiver->_capacity)
|
||||
if (NO == GSPutFastNonBlockingFIFO(receiver, item))
|
||||
{
|
||||
receiver->_items[receiver->_head % receiver->_capacity] = item;
|
||||
receiver->_head++;
|
||||
return;
|
||||
[receiver put: item];
|
||||
}
|
||||
[receiver put: item];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
63
GSFIFO.m
63
GSFIFO.m
|
@ -41,6 +41,11 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSUInteger) count
|
||||
{
|
||||
return (NSUInteger)(_head - _tail);
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat:
|
||||
|
@ -194,5 +199,63 @@
|
|||
[putLock unlock];
|
||||
}
|
||||
|
||||
- (id) tryGet
|
||||
{
|
||||
id obj;
|
||||
|
||||
if (nil == getLock)
|
||||
{
|
||||
if (_head > _tail)
|
||||
{
|
||||
obj = _items[_tail % _capacity];
|
||||
_tail++;
|
||||
return obj;
|
||||
}
|
||||
emptyCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
[getLock lock];
|
||||
if (_head > _tail)
|
||||
{
|
||||
obj = _items[_tail % _capacity];
|
||||
_tail++;
|
||||
[getLock unlock];
|
||||
return obj;
|
||||
}
|
||||
emptyCount++;
|
||||
[getLock unlock];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) tryPut: (id)item
|
||||
{
|
||||
if (nil == putLock)
|
||||
{
|
||||
if (_head - _tail < _capacity)
|
||||
{
|
||||
_items[_head % _capacity] = item;
|
||||
_head++;
|
||||
return YES;
|
||||
}
|
||||
fullCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
[putLock lock];
|
||||
if (_head - _tail < _capacity)
|
||||
{
|
||||
_items[_head % _capacity] = item;
|
||||
_head++;
|
||||
[putLock unlock];
|
||||
return YES;
|
||||
}
|
||||
fullCount++;
|
||||
[putLock unlock];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in a new issue