Optionally allow the caller to specify the time it wants to block on an

empty FIFO. This supplements the existing method of having a timeout on
the FIFO, and does not raise an excepion when the wait time is too long.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/performance/trunk@38814 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Niels Grewe 2015-07-17 20:08:38 +00:00
parent 74d1c92669
commit 6f267319e3
3 changed files with 102 additions and 13 deletions

View file

@ -1,3 +1,9 @@
2015-07-17 Niels Grewe <niels.grewe@halbordnung.de>
* GSFIFO.m: Implement methods that allow waiting on an empty
FIFO for an arbitrary period of time, without raising an
exception.
2015-07-16 Niels Grewe <niels.grewe@halbordnung.de>
* GSFIFO.m: Implement -sizeInBytesExcluding:

View file

@ -118,6 +118,17 @@
*/
- (unsigned) get: (void**)buf count: (unsigned)count shouldBlock: (BOOL)block;
/**
* Reads up to count items from the FIFO into the buf. If blocking is requested
* and a before date is specified, the operation blocks until the specified time
* and returns 0 if it could not read any items. The timeout configured for the
* FIFO still takes precedence.
*/
- (unsigned) get: (void**)buf
count: (unsigned)count
shouldBlock: (BOOL)block
before: (NSDate*)date;
/** Reads up to count objects from the FIFO (which must contain objects
* or nil items) into buf and autoreleases them.<br />
* If block is YES, this blocks if necessary until at least one object
@ -129,6 +140,18 @@
count: (unsigned)count
shouldBlock: (BOOL)block;
/**
* Reads up to count autoreleased objects from the FIFO into the buf. If blocking
* is requested and a before date is specified, the operation blocks until the
* specified time and returns 0 if it could not read any items. The timeout
* configured for the FIFO still takes precedence.
*/
- (unsigned) getObjects: (NSObject**)buf
count: (unsigned)count
shouldBlock: (BOOL)block
before: (NSDate*)date;
/** Gets the next item from the FIFO, blocking if necessary until an
* item is available. Raises an exception if the FIFO is configured
* with a timeout and it is exceeded.<br />

View file

@ -128,6 +128,7 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
- (unsigned) _cooperatingGet: (void**)buf
count: (unsigned)count
shouldBlock: (BOOL)block
before: (NSDate*)before
{
NSTimeInterval ti;
unsigned index;
@ -145,7 +146,7 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
}
START
if (0 == timeout)
if ((0 == timeout) && (before == nil))
{
while (_head - _tail == 0)
{
@ -155,22 +156,47 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
else
{
NSDate *d;
d = [[NSDateClass alloc]
initWithTimeIntervalSinceNow: timeout / 1000.0f];
NSDate *effective;
[before retain];
if (timeout != 0)
{
d = [[NSDateClass alloc]
initWithTimeIntervalSinceNow: timeout / 1000.0f];
}
if ((d != nil) && (before != nil))
{
effective = [d earlierDate: before];
}
else if (d != nil)
{
effective = d;
}
else
{
effective = before;
}
while (_head - _tail == 0)
{
if (NO == [condition waitUntilDate: d])
if (NO == [condition waitUntilDate: effective])
{
[d release];
[before release];
ENDGET
[condition broadcast];
[condition unlock];
[NSException raise: NSGenericException
format: @"Timeout waiting for new data in FIFO"];
if (before != effective)
{
[NSException raise: NSGenericException
format: @"Timeout waiting for new data in FIFO"];
}
else
{
return 0;
}
}
}
[d release];
[before release];
ENDGET
}
}
@ -383,21 +409,28 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
fullCount];
}
- (unsigned) get: (void**)buf count: (unsigned)count shouldBlock: (BOOL)block
- (unsigned) get: (void**)buf
count: (unsigned)count
shouldBlock: (BOOL)block
before: (NSDate*)date
{
unsigned index;
NSTimeInterval ti;
NSTimeInterval sum;
NSTimeInterval waitLength;
uint32_t old;
uint32_t fib;
uint32_t fib;
if (0 == count) return 0;
if (nil != condition)
{
return [self _cooperatingGet: buf count: count shouldBlock: block];
return [self _cooperatingGet: buf
count: count
shouldBlock: block
before: date];
}
waitLength = [date timeIntervalSinceNow];
if (nil == getThread)
{
getThread = [NSThread currentThread];
@ -434,6 +467,11 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
[NSException raise: NSGenericException
format: @"Timeout waiting for new data in FIFO"];
}
else if (date != nil && sum > waitLength)
{
ENDGET
return 0;
}
tmp = fib + old;
old = fib;
fib = tmp;
@ -454,14 +492,26 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
return index;
}
- (unsigned) get: (void**)buf count: (unsigned)count shouldBlock: (BOOL)block
{
return [self get: buf count: count shouldBlock: block before: nil];
}
- (unsigned) getObjects: (NSObject**)buf
count: (unsigned)count
shouldBlock: (BOOL)block
before: (NSDate*)date
{
unsigned result;
unsigned index;
index = result = [self get: (void**)buf count: count shouldBlock: block];
index = result = [self get: (void**)buf
count: count
shouldBlock: block
before: date];
while (index-- > 0)
{
[buf[index] autorelease];
@ -469,6 +519,16 @@ stats(NSTimeInterval ti, uint32_t max, NSTimeInterval *bounds, uint64_t *bands)
return result;
}
- (unsigned) getObjects: (NSObject**)buf
count: (unsigned)count
shouldBlock: (BOOL)block
{
return [self getObjects: buf
count: count
shouldBlock: block
before: nil];
}
- (void*) get
{
void *item = 0;