mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-10 04:25:35 +00:00
8180399: move jdk.testlibrary.LockFreeLogManager to the top level test library
Reviewed-by: psandoz, mchung
This commit is contained in:
parent
97a536003e
commit
2d7f46e91b
@ -27,7 +27,7 @@ import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
import jdk.testlibrary.LockFreeLogManager;
|
||||
import jdk.test.lib.LockFreeLogger;
|
||||
import jdk.testlibrary.Utils;
|
||||
|
||||
/**
|
||||
@ -100,7 +100,7 @@ public class ThreadStateController extends Thread {
|
||||
private final AtomicInteger iterations = new AtomicInteger();
|
||||
private final AtomicInteger interrupted = new AtomicInteger();
|
||||
|
||||
private final LockFreeLogManager logManager = new LockFreeLogManager();
|
||||
private final LockFreeLogger logger = new LockFreeLogger();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@ -349,7 +349,7 @@ public class ThreadStateController extends Thread {
|
||||
}
|
||||
|
||||
private void log(String msg, Object ... params) {
|
||||
logManager.log(msg, params);
|
||||
logger.log(msg, params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,6 +361,6 @@ public class ThreadStateController extends Thread {
|
||||
public String getLog() throws InterruptedException {
|
||||
this.join();
|
||||
|
||||
return logManager.toString();
|
||||
return logger.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ import static java.lang.Thread.State.*;
|
||||
*
|
||||
* @author Mandy Chung
|
||||
* @library /lib/testlibrary
|
||||
* @library /test/lib
|
||||
* @build jdk.testlibrary.*
|
||||
* @build ThreadStateTest ThreadStateController
|
||||
* @run main/othervm -Xmixed ThreadStateTest
|
||||
|
||||
@ -29,17 +29,17 @@
|
||||
* @author Mandy Chung
|
||||
* @author Jaroslav Bachorik
|
||||
*
|
||||
* @library /lib/testlibrary
|
||||
* @library /test/lib
|
||||
*
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main/othervm Locks
|
||||
*/
|
||||
import java.lang.management.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Phaser;
|
||||
import java.util.function.Predicate;
|
||||
import jdk.testlibrary.LockFreeLogManager;
|
||||
import jdk.test.lib.LockFreeLogger;
|
||||
|
||||
public class Locks {
|
||||
|
||||
@ -47,7 +47,7 @@ public class Locks {
|
||||
private static final Object OBJB = new Object();
|
||||
private static final EnhancedWaiter OBJC = new EnhancedWaiter();
|
||||
private static final ThreadMXBean TM = ManagementFactory.getThreadMXBean();
|
||||
private static final LockFreeLogManager LOGGER = new LockFreeLogManager();
|
||||
private static final LockFreeLogger LOGGER = new LockFreeLogger();
|
||||
|
||||
private static String getLockName(Object lock) {
|
||||
if (lock == null) return null;
|
||||
@ -60,12 +60,12 @@ public class Locks {
|
||||
if (t == null) {
|
||||
return;
|
||||
}
|
||||
Optional<ThreadInfo> result = Arrays.asList(
|
||||
TM.getThreadInfo(TM.getAllThreadIds(), true, true)).
|
||||
stream().
|
||||
filter(tInfo -> (tInfo != null && tInfo.getLockOwnerName() != null)
|
||||
? tInfo.getLockOwnerName().equals(t.getName()) : false).
|
||||
findAny();
|
||||
String name = t.getName();
|
||||
Optional<ThreadInfo> result = Arrays.stream(
|
||||
TM.getThreadInfo(TM.getAllThreadIds(), true, true))
|
||||
.filter(Objects::nonNull)
|
||||
.filter(i -> name.equals(i.getLockOwnerName()))
|
||||
.findAny();
|
||||
if (result.isPresent()) {
|
||||
throw new RuntimeException("Thread " + t.getName() + " is not "
|
||||
+ "supposed to be hold any lock. Currently owning lock : "
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
*
|
||||
* @library ../../Thread
|
||||
* @library /lib/testlibrary
|
||||
* @library /test/lib
|
||||
*
|
||||
* @build jdk.testlibrary.*
|
||||
* @build ThreadMXBeanStateTest ThreadStateController
|
||||
|
||||
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.testlibrary;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Formatter;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A log manager designed specifically to allow collecting ordered log messages
|
||||
* in a multi-threaded environment without involving any kind of locking.
|
||||
* <p>
|
||||
* It is particularly useful in situations when one needs to assert various
|
||||
* details about the tested thread state or the locks it hold while also wanting
|
||||
* to produce diagnostic log messages.
|
||||
* <p>
|
||||
* The log manager does not provide any guarantees about the completness of the
|
||||
* logs written from different threads - it is up to the caller to make sure
|
||||
* {@code toString()} method is called only when all the activity has ceased
|
||||
* and the per-thread logs contain all the necessary data.
|
||||
*
|
||||
* @author Jaroslav Bachorik
|
||||
**/
|
||||
public class LockFreeLogManager {
|
||||
private final AtomicInteger logCntr = new AtomicInteger(0);
|
||||
private final Collection<Map<Integer, String>> allRecords = new ConcurrentLinkedQueue<>();
|
||||
private final ThreadLocal<Map<Integer, String>> records = new ThreadLocal<Map<Integer, String>>() {
|
||||
@Override
|
||||
protected Map<Integer, String> initialValue() {
|
||||
Map<Integer, String> m = new ConcurrentHashMap<>();
|
||||
allRecords.add(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Log a message
|
||||
* @param format Message format
|
||||
* @param params Message parameters
|
||||
*/
|
||||
public void log(String format, Object ... params) {
|
||||
int id = logCntr.getAndIncrement();
|
||||
try (Formatter formatter = new Formatter()) {
|
||||
records.get().put(id, formatter.format(format, params).toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will generate an aggregated log of chronologically ordered messages.
|
||||
* <p>
|
||||
* Make sure that you call this method only when all the related threads
|
||||
* have finished; otherwise you might get incomplete data.
|
||||
*
|
||||
* @return An aggregated log of chronologically ordered messages
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return allRecords.stream()
|
||||
.flatMap(m->m.entrySet().stream())
|
||||
.sorted((l, r)->l.getKey().compareTo(r.getKey()))
|
||||
.map(e->e.getValue())
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user