blob: c30713aae52b071827989635e2ef22427840f18c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/*
* This benchmark has been ported from "The Computer Language Benchmarks Game" suite and
* significantly modified to fit the benchmarking framework.
*
* Originally the benchmark finished with 'System.exit(0)'. A new state of message "-1" was
* introduced to avoid this.
*
* The original file is `threadring/threadring.java-3.java` from the archive
* available at
* http://benchmarksgame.alioth.debian.org/download/benchmarksgame-sourcecode.zip.
* See LICENSE file in the same folder (BSD 3-clause)
*
* The Computer Language Benchmarks Game
* http://benchmarksgame.alioth.debian.org/
* contributed by Klaus Friedel
*/
/*
* Description: Switch from thread to thread passing one token.
* Main Focus: TODO
*
*/
package org.linaro.benchmarks.benchmarksgame;
import java.util.concurrent.locks.LockSupport;
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Benchmark)
// CHECKSTYLE.OFF: .*
public class threadring {
// CHECKSTYLE.ON: .*
static final int THREAD_COUNT = 503;
private static String lastActedThreadName;
public static class MessageThread extends Thread {
MessageThread nextThread;
volatile Integer message;
public MessageThread(MessageThread nextThread, int name) {
super("" + name);
this.nextThread = nextThread;
}
public void run() {
Integer msg = dequeue();
while (nextThread.enqueue(msg)) {
msg = dequeue();
if (msg == -1) {
break;
}
}
}
public boolean enqueue(Integer hopsRemaining) {
if (hopsRemaining == 0) {
message = -1;
lastActedThreadName = this.getName();
// notify all the threads that transmission is over
LockSupport.unpark(this);
MessageThread current = nextThread;
while (current != this) {
current.message = -1;
LockSupport.unpark(current);
current = current.nextThread;
}
return false;
}
message = hopsRemaining - 1;
LockSupport.unpark(this);
return true;
}
private Integer dequeue() {
while (message == null) {
LockSupport.park();
}
Integer msg = message;
if (msg != -1) {
message = null;
}
return msg;
}
}
@Benchmark
public void jmhTimeThreadRing() throws Exception {
int hopCount = 1000;
MessageThread first = null;
MessageThread last = null;
for (int i = THREAD_COUNT; i >= 1; i--) {
first = new MessageThread(first, i);
if (i == THREAD_COUNT) {
last = first;
}
}
// close the ring:
last.nextThread = first;
// start all Threads
MessageThread t = first;
do {
t.start();
t = t.nextThread;
} while (t != first);
first.enqueue(hopCount);
first.join(); // wait for System.exit
}
}
|