>> Here's a port of a fast pathed semaphore I did elsewhere. It
>> only does single permit acquire and release. If you use it
[quoted text clipped - 3 lines]
>>
> What benchmarks did you use? Code?
>>> Here's a port of a fast pathed semaphore I did elsewhere. It
>>> only does single permit acquire and release. If you use it
[quoted text clipped - 5 lines]
>
> I'm curious, too, how it compares to j.u.c.Semaphore.
I'm rewriting the testcase to make it a bit more compact. It was a bit
large for posting.
The contention is set artifically* high, a bunch of threads doing queue
operations on a queue that's non empty most of the time.
* for normal usage unless you were doing a high throuput server or something
like that.

Signature
Joe Seigh
When you get lemons, you make lemonade.
When you get hardware, you make software.
>>> Here's a port of a fast pathed semaphore I did elsewhere. It
>>> only does single permit acquire and release. If you use it
[quoted text clipped - 5 lines]
>
> I'm curious, too, how it compares to j.u.c.Semaphore.
Ok. I have a new design pattern that subsets interfaces so
I can compare apple to orange implementations without having
to implement the fruit, plant, multi-celled organism, cell,
dna, organic molecule, molecule, and atom interfaces for
orange. Java's architects really have nothing better to do
with other people's time.
import java.util.LinkedList;
import java.util.concurrent.*;
import java.util.*;
interface Sem {
public void acquire() throws InterruptedException;
public void release();
}
class NSem extends Semaphore implements Sem {
public NSem(int n, boolean fair) {super(n, fair); }
}
class FSem extends FastSemaphore implements Sem {
public FSem(int n, boolean fair) { super(n, fair); }
}
interface fifo<T> {
public void queue(T o);
public T dequeue() throws InterruptedException;
}
class ConcurrentFifoQueue<T>
implements fifo<T>
{
ConcurrentLinkedQueue<T> queue;
Sem sem;
ConcurrentFifoQueue(Sem s) {
queue = new ConcurrentLinkedQueue<T>();
sem = s;
}
public void queue(T o) {
queue.offer(o);
sem.release();
}
public T dequeue() throws InterruptedException {
sem.acquire();
return queue.poll();
}
}
class BlockingFifoQueue<T>
extends java.util.concurrent.LinkedBlockingQueue<T>
implements fifo<T>
{
public void queue(T o) { try {put(o); } catch (InterruptedException e) {} }
public T dequeue() throws InterruptedException { return take(); }
}
public class qtest {
/**
* multi-threaded queueing test
*
*/
final static int loopcount = 20000;
final static int nodecount = 200;
final static int threadcount = 20;
final static Formatter fmt = new java.util.Formatter(System.out);
public void test(final fifo<Object> fullq, final fifo<Object> emptyq, String desc) {
int j;
long t0, t1; // start, stop times
Thread producer[] = new Thread[threadcount];
Thread consumer[] = new Thread[threadcount];
final CyclicBarrier barrier = new CyclicBarrier(producer.length + consumer.length + 1);
for (j = 0; j < nodecount; j++) {
emptyq.queue(new Object());
}
for (j = 0; j < producer.length; j++) {
producer[j] = new Thread(new Runnable() {
public void run() {
try {barrier.await(); } catch (Exception e) {}
for (int j = 0; j < loopcount; j++) {
try {fullq.queue(emptyq.dequeue()); } catch (InterruptedException e) {}
}
try {barrier.await(); } catch (Exception e) {}
}
});
producer[j].setDaemon(true);
producer[j].start();
}
for (j = 0; j < consumer.length; j++) {
consumer[j] = new Thread(new Runnable() {
public void run() {
try {barrier.await(); } catch (Exception e) {}
for (int j = 0; j < loopcount; j++) {
try {emptyq.queue(fullq.dequeue()); } catch (InterruptedException e) {}
}
try {barrier.await(); } catch (Exception e) {}
}
});
consumer[j].setDaemon(true);
consumer[j].start();
}
try {barrier.await(); } catch (Exception e) {}
t0 = System.nanoTime();
try {barrier.await(); } catch (Exception e) {}
t1 = System.nanoTime();
double x = ((t1 - t0)/1e9);
System.out.println(desc + ":");
fmt.format("runtime = %12.9f secs\n\n", x);
}
public static void main(String[] args) {
qtest q = new qtest();
fmt.format("loop count = %6d\n", loopcount);
fmt.format("queue size = %6d\n", nodecount);
fmt.format("producer count = %6d\n", threadcount);
fmt.format("consumer count = %6d\n\n", threadcount);
q.test(
new BlockingFifoQueue<Object>(),
new BlockingFifoQueue<Object>(),
"LinkedBlockingQueue");
q.test(
new ConcurrentFifoQueue<Object>(new NSem(0, false)),
new ConcurrentFifoQueue<Object>(new NSem(0, false)),
"ConcurrentLinkedQueue w/ unfair semaphore");
q.test(
new ConcurrentFifoQueue<Object>(new NSem(0, true)),
new ConcurrentFifoQueue<Object>(new NSem(0, true)),
"ConcurrentLinkedQueue w/ fair semaphore");
q.test(
new ConcurrentFifoQueue<Object>(new FSem(0, false)),
new ConcurrentFifoQueue<Object>(new FSem(0, false)),
"ConcurrentLinkedQueue w/ unfair fast semaphore");
q.test(
new ConcurrentFifoQueue<Object>(new FSem(0, true)),
new ConcurrentFifoQueue<Object>(new FSem(0, true)),
"ConcurrentLinkedQueue w/ fair fast semaphore");
System.out.println("qtest exiting...");
}
}

Signature
Joe Seigh
When you get lemons, you make lemonade.
When you get hardware, you make software.