Skip to content
Permalink
Browse files

Add "subtask" variants of start, stop, and event

Sub tasks are meant for use when the task name is a concatenation of two, runtime constant
strings, but the caller doesn't want to pay the allocation cost.  None of these methods
support Tag overloads, and instead expect callers to invoke attachTag instead.

Perf:

```
Benchmark                                                  Mode  Cnt   Score   Error  Units
VarHandleGeneratorBenchmark.getAndSetAndGetGeneration      avgt    5   2.610 ± 0.022  ns/op
VarHandleGeneratorBenchmark.getGeneration                  avgt    5   2.379 ± 0.330  ns/op
VarHandleGeneratorBenchmark.racyGetAndSetAndGetGeneration  avgt    5  21.905 ± 2.327  ns/op
VarHandleMarkHolderBenchmark.event_name_noTag              avgt    5   3.581 ± 0.178  ns/op
VarHandleMarkHolderBenchmark.event_name_subname            avgt    5   4.131 ± 0.058  ns/op
VarHandleMarkHolderBenchmark.event_name_tag                avgt    5   4.417 ± 0.083  ns/op
VarHandleMarkHolderBenchmark.link                          avgt    5   2.301 ± 0.038  ns/op
VarHandleMarkHolderBenchmark.start_name_noTag              avgt    5   3.460 ± 0.048  ns/op
VarHandleMarkHolderBenchmark.start_name_subname            avgt    5   3.987 ± 0.090  ns/op
VarHandleMarkHolderBenchmark.start_name_tag                avgt    5   4.448 ± 0.082  ns/op
VarHandleMarkHolderBenchmark.stop_name_noTag               avgt    5   3.505 ± 0.042  ns/op
VarHandleMarkHolderBenchmark.stop_name_subname             avgt    5   4.019 ± 0.056  ns/op
VarHandleMarkHolderBenchmark.stop_name_tag                 avgt    5   4.503 ± 0.054  ns/op

Benchmark                                                 Mode  Cnt   Score   Error  Units
SynchronizedMarkHolderBenchmark.event_name_noTag          avgt    5   5.910 ± 0.077  ns/op
SynchronizedMarkHolderBenchmark.event_name_subname        avgt    5   7.843 ± 0.064  ns/op
SynchronizedMarkHolderBenchmark.event_name_tag            avgt    5   9.060 ± 0.116  ns/op
SynchronizedMarkHolderBenchmark.link                      avgt    5   3.474 ± 0.051  ns/op
SynchronizedMarkHolderBenchmark.start_name_noTag          avgt    5   5.849 ± 0.067  ns/op
SynchronizedMarkHolderBenchmark.start_name_subname        avgt    5   7.791 ± 0.093  ns/op
SynchronizedMarkHolderBenchmark.start_name_tag            avgt    5   9.105 ± 0.176  ns/op
SynchronizedMarkHolderBenchmark.stop_name_noTag           avgt    5   6.595 ± 0.109  ns/op
SynchronizedMarkHolderBenchmark.stop_name_subname         avgt    5   7.993 ± 0.071  ns/op
SynchronizedMarkHolderBenchmark.stop_name_tag             avgt    5   9.195 ± 0.082  ns/op
VolatileGeneratorBenchmark.getAndSetAndGetGeneration      avgt    5   7.712 ± 0.121  ns/op
VolatileGeneratorBenchmark.getGeneration                  avgt    5   2.262 ± 0.012  ns/op
VolatileGeneratorBenchmark.ifEnabled                      avgt    5   0.692 ± 0.007  ns/op
VolatileGeneratorBenchmark.racyGetAndSetAndGetGeneration  avgt    5  93.333 ± 2.295  ns/op
```
  • Loading branch information...
carl-mastrangelo committed Nov 7, 2019
1 parent 2416627 commit b559363aecef13dd75b675ef288717e92b53b864
@@ -43,14 +43,20 @@ protected void startTask(String taskName, Tag tag) {}

protected void startTask(String taskName) {}

protected void startTask(String taskName, String subTaskName) {}

protected void event(String eventName, Tag tag) {}

protected void event(String eventName) {}

protected void event(String eventName, String subEventName) {}

protected void stopTask(String taskName, Tag tag) {}

protected void stopTask(String taskName) {}

protected void stopTask(String taskName, String subTaskName) {}

protected Link linkOut() {
return NO_LINK;
}
@@ -95,14 +95,17 @@ public static void startTask(String taskName) {
}

/**
* Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The name of the
* task should be a runtime-time constant, usually a string literal. Tasks with the same name can
* be grouped together for analysis later, so avoid using too many unique task names.
* Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The names of
* the task and subtask should be runtime-time constants, usually a string literal. Tasks with the
* same name can be grouped together for analysis later, so avoid using too many unique task
* names.
*
* @param taskName the name of the task.
* @param subTaskName the name of the sub task
* @since 0.20.0
*/
public static void startTask(String taskName, String subTaskName) {
impl.startTask(taskName + subTaskName);
impl.startTask(taskName, subTaskName);
}

/**
@@ -132,6 +135,19 @@ public static void event(String eventName) {
impl.event(eventName);
}

/**
* Marks an event. Events are logically both a task start and a task end. Events have no duration
* associated. Events still represent the instant something occurs. If PerfMark is disabled, this
* method is a no-op.
*
* @param eventName the name of the event.
* @param subEventName the name of the sub event.
* @since 0.20.0
*/
public static void event(String eventName, String subEventName) {
impl.event(eventName, subEventName);
}

/**
* Marks the end of a task. If PerfMark is disabled, this method is a no-op. The task name and tag
* should match the ones provided to the corresponding {@link #startTask(String, Tag)}. If the
@@ -165,6 +181,24 @@ public static void stopTask(String taskName) {
impl.stopTask(taskName);
}

/**
* Marks the end of a task. If PerfMark is disabled, this method is a no-op. The task name should
* match the ones provided to the corresponding {@link #startTask(String, String)}. If the task
* name or tag do not match, the implementation may not be able to associate the starting and
* stopping of a single task. The name of the task should be a runtime-time constant, usually a
* string literal.
*
* <p>It is important that {@link #stopTask} always be called after starting a task, even in case
* of exceptions. Failing to do so may result in corrupted results.
*
* @param taskName the name of the task being ended.
* @param subTaskName the name of the sub task being ended.
* @since 0.20.0
*/
public static void stopTask(String taskName, String subTaskName) {
impl.stopTask(taskName, subTaskName);
}

/**
* Creates a tag with no name or numeric identifier. The returned instance is different based on
* if PerfMark is enabled or not.
@@ -26,16 +26,22 @@

public abstract void start(long gen, String taskName, long nanoTime);

public abstract void start(long gen, String taskName, String subTaskName, long nanoTime);

public abstract void link(long gen, long linkId);

public abstract void stop(long gen, String taskName, String tagName, long tagId, long nanoTime);

public abstract void stop(long gen, String taskName, long nanoTime);

public abstract void stop(long gen, String taskName, String subTaskName, long nanoTime);

public abstract void event(long gen, String eventName, String tagName, long tagId, long nanoTime);

public abstract void event(long gen, String eventName, long nanoTime);

public abstract void event(long gen, String eventName, String subEventName, long nanoTime);

public abstract void attachTag(long gen, String tagName, long tagId);

public abstract void resetForTest();
@@ -37,6 +37,9 @@ public void start(long gen, String taskName, String tagName, long tagId, long na
@Override
public void start(long gen, String taskName, long nanoTime) {}

@Override
public void start(long gen, String taskName, String subTaskName, long nanoTime) {}

@Override
public void link(long gen, long linkId) {}

@@ -46,12 +49,18 @@ public void stop(long gen, String taskName, String tagName, long tagId, long nan
@Override
public void stop(long gen, String taskName, long nanoTime) {}

@Override
public void stop(long gen, String taskName, String subTaskName, long nanoTime) {}

@Override
public void event(long gen, String eventName, String tagName, long tagId, long nanoTime) {}

@Override
public void event(long gen, String eventName, long nanoTime) {}

@Override
public void event(long gen, String eventName, String subEventName, long nanoTime) {}

@Override
public void attachTag(long gen, String tagName, long tagId) {}

@@ -161,6 +161,15 @@ protected void startTask(String taskName) {
Storage.startAnyways(gen, taskName);
}

@Override
protected void startTask(String taskName, String subTaskName) {
final long gen = getGen();
if (!isEnabled(gen)) {
return;
}
Storage.startAnyways(gen, taskName, subTaskName);
}

@Override
protected void stopTask(String taskName, Tag tag) {
final long gen = getGen();
@@ -179,6 +188,15 @@ protected void stopTask(String taskName) {
Storage.stopAnyways(gen, taskName);
}

@Override
protected void stopTask(String taskName, String subTaskName) {
final long gen = getGen();
if (!isEnabled(gen)) {
return;
}
Storage.stopAnyways(gen, taskName, subTaskName);
}

@Override
protected void event(String eventName, Tag tag) {
final long gen = getGen();
@@ -197,6 +215,15 @@ protected void event(String eventName) {
Storage.eventAnyways(gen, eventName);
}

@Override
protected void event(String eventName, String subEventName) {
final long gen = getGen();
if (!isEnabled(gen)) {
return;
}
Storage.eventAnyways(gen, eventName, subEventName);
}

@Override
protected void attachTag(Tag tag) {
final long gen = getGen();
@@ -154,6 +154,10 @@ static void startAnyways(long gen, String taskName) {
localMarkHolder.get().start(gen, taskName, System.nanoTime());
}

static void startAnyways(long gen, String taskName, String subTaskName) {
localMarkHolder.get().start(gen, taskName, subTaskName, System.nanoTime());
}

static void stopAnyways(long gen, String taskName, @Nullable String tagName, long tagId) {
long nanoTime = System.nanoTime();
localMarkHolder.get().stop(gen, taskName, tagName, tagId, nanoTime);
@@ -164,6 +168,11 @@ static void stopAnyways(long gen, String taskName) {
localMarkHolder.get().stop(gen, taskName, nanoTime);
}

static void stopAnyways(long gen, String taskName, String subTaskName) {
long nanoTime = System.nanoTime();
localMarkHolder.get().stop(gen, taskName, subTaskName, nanoTime);
}

static void eventAnyways(long gen, String eventName, @Nullable String tagName, long tagId) {
long nanoTime = System.nanoTime();
localMarkHolder.get().event(gen, eventName, tagName, tagId, nanoTime);
@@ -174,6 +183,11 @@ static void eventAnyways(long gen, String eventName) {
localMarkHolder.get().event(gen, eventName, nanoTime);
}

static void eventAnyways(long gen, String eventName, String subEventName) {
long nanoTime = System.nanoTime();
localMarkHolder.get().event(gen, eventName, subEventName, nanoTime);
}

static void linkAnyways(long gen, long linkId) {
localMarkHolder.get().link(gen, linkId);
}
@@ -43,6 +43,13 @@ public void start_name_noTag() {
markHolder.start(1, "hi", 1234);
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void start_name_subname() {
markHolder.start(1, "hi", "there", 1234);
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@@ -57,6 +64,13 @@ public void stop_name_noTag() {
markHolder.stop(1, "hi", 1234);
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void stop_name_subname() {
markHolder.stop(1, "hi", "there", 1234);
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@@ -77,4 +91,11 @@ public void event_name_tag() {
public void event_name_noTag() {
markHolder.event(1, "hi", 2);
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public void event_name_subname() {
markHolder.event(1, "hi", "there", 2);
}
}
@@ -86,6 +86,13 @@ private void writeNnss(long genOp, long n0, long n1, String s0, String s1) {
nums[(int) (nIdx++ & maxEventsMask)] = genOp;
}

private void writeNss(long genOp, long n0, String s0, String s1) {
nums[(int) (nIdx++ & maxEventsMask)] = n0;
strings[(int) (sIdx++ & maxEventsMask)] = s0;
strings[(int) (sIdx++ & maxEventsMask)] = s1;
nums[(int) (nIdx++ & maxEventsMask)] = genOp;
}

private void writeNs(long genOp, long n0, String s0) {
nums[(int) (nIdx++ & maxEventsMask)] = n0;
strings[(int) (sIdx++ & maxEventsMask)] = s0;
@@ -109,6 +116,11 @@ public synchronized void start(long gen, String taskName, long nanoTime) {
writeNs(gen + START_N1S1_OP, nanoTime, taskName);
}

@Override
public synchronized void start(long gen, String taskName, String subTaskName, long nanoTime) {
writeNss(gen + START_N1S2_OP, nanoTime, taskName, subTaskName);
}

@Override
public synchronized void link(long gen, long linkId) {
writeN(gen + LINK_OP, linkId);
@@ -126,6 +138,11 @@ public synchronized void stop(long gen, String taskName, long nanoTime) {
writeNs(gen + STOP_N1S1_OP, nanoTime, taskName);
}

@Override
public synchronized void stop(long gen, String taskName, String subTaskName, long nanoTime) {
writeNss(gen + STOP_N1S2_OP, nanoTime, taskName, subTaskName);
}

@Override
public synchronized void event(
long gen, String eventName, String tagName, long tagId, long nanoTime) {
@@ -137,6 +154,11 @@ public synchronized void event(long gen, String eventName, long nanoTime) {
writeNs(gen + EVENT_N1S1_OP, nanoTime, eventName);
}

@Override
public synchronized void event(long gen, String eventName, String subEventName, long nanoTime) {
writeNss(gen + EVENT_N1S2_OP, nanoTime, eventName, subEventName);
}

@Override
public synchronized void attachTag(long gen, String tagName, long tagId) {
writeNs(gen + TAG_N1S1_OP, tagId, tagName);
@@ -208,21 +230,33 @@ public synchronized void resetForTest() {
marks.addFirst(Mark.taskStart(gen, n1, s1));
break;
case TASK_START_N1S2:
throw new UnsupportedOperationException();
n1 = numQ.remove();
s2 = stringQ.remove();
s1 = stringQ.remove();
marks.addFirst(Mark.taskStart(gen, n1, s1, s2));
break;
case TASK_END_N1S1:
n1 = numQ.remove();
s1 = stringQ.remove();
marks.addFirst(Mark.taskEnd(gen, n1, s1));
break;
case TASK_END_N1S2:
throw new UnsupportedOperationException();
n1 = numQ.remove();
s2 = stringQ.remove();
s1 = stringQ.remove();
marks.addFirst(Mark.taskEnd(gen, n1, s1, s2));
break;
case EVENT_N1S1:
n1 = numQ.remove();
s1 = stringQ.remove();
marks.addFirst(Mark.event(gen, n1, s1));
break;
case EVENT_N1S2:
throw new UnsupportedOperationException();
n1 = numQ.remove();
s2 = stringQ.remove();
s1 = stringQ.remove();
marks.addFirst(Mark.event(gen, n1, s1, s2));
break;
case EVENT_N2S2:
n2 = numQ.remove();
s2 = stringQ.remove();
@@ -43,6 +43,19 @@ public void taskTagStartStop() {
assertEquals(expected, marks);
}

@Test
public void taskTagStartStop_subTask() {
mh.start(gen, "task", "subtask", 3);
mh.stop(gen, "task", "subtask", 4);

List<Mark> marks = mh.read(false);
assertEquals(2, marks.size());
List<Mark> expected =
Arrays.asList(
Mark.taskStart(gen, 3, "task", "subtask"), Mark.taskEnd(gen, 4, "task", "subtask"));
assertEquals(expected, marks);
}

@Test
public void taskTagStartStop_tag() {
mh.start(gen, "task", "tag", 9, 3);
@@ -118,6 +131,20 @@ public void event_tag() {
assertEquals(expected, marks);
}

@Test
public void event_subevent() {
mh.event(gen, "task1", "subtask3", 8);
mh.event(gen, "task2", "subtask4", 5);

List<Mark> marks = mh.read(false);

assertEquals(2, marks.size());
List<Mark> expected =
Arrays.asList(
Mark.event(gen, 8, "task1", "subtask3"), Mark.event(gen, 5, "task2", "subtask4"));
assertEquals(expected, marks);
}

@Test
public void linkInLinkOut() {
mh.start(gen, "task1", 3);

0 comments on commit b559363

Please sign in to comment.
You can’t perform that action at this time.