mirror of
https://github.com/gnustep/libs-performance.git
synced 2025-02-15 16:11:14 +00:00
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:
parent
74d1c92669
commit
6f267319e3
3 changed files with 102 additions and 13 deletions
|
@ -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:
|
||||
|
|
23
GSFIFO.h
23
GSFIFO.h
|
@ -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 />
|
||||
|
|
86
GSFIFO.m
86
GSFIFO.m
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue