📄 aemonsem.java
字号:
/*
* Created on 22-Sep-2004
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package org.gudy.azureus2.core3.util;
import java.util.*;
/**
* @author parg
*
*/
public abstract class
AEMonSem
{
protected static boolean DEBUG = AEDiagnostics.DEBUG_MONITOR_SEM_USAGE;
protected static boolean DEBUG_CHECK_DUPLICATES = false;
protected static long DEBUG_TIMER = 30000;
protected static AEDiagnosticsLogger diag_logger;
private static ThreadLocal tls =
new ThreadLocal()
{
public Object
initialValue()
{
return( new Stack());
}
};
private static long monitor_id_next;
private static long semaphore_id_next;
private static Map debug_traces = new HashMap();
private static List debug_recursions = new ArrayList();
private static List debug_reciprocals = new ArrayList();
//private static List debug_sem_in_mon = new ArrayList();
private static Map debug_name_mapping = new WeakHashMap();
private static Map debug_monitors = new WeakHashMap();
private static Map debug_semaphores = new WeakHashMap();
static{
if ( DEBUG ){
// add known and validated exceptions
debug_recursions.add( "ResourceDownloader" ); // known tree recursion
debug_recursions.add( "ConnectionPool:CP" ); // known tree recursion
debug_recursions.add( "(S)RDRretry" ); // RDretry sem left on stack after 1st d/l so appears recursive on subsequent
diag_logger = AEDiagnostics.getLogger( "monsem" );
new Timer("AEMonSem").addPeriodicEvent(
DEBUG_TIMER,
new TimerEventPerformer()
{
public void
perform(
TimerEvent event )
{
check();
}
});
}
}
protected static void
check()
{
List active = new ArrayList();
List waiting_monitors = new ArrayList();
List busy_monitors = new ArrayList();
List waiting_semaphores = new ArrayList();
synchronized( AEMonSem.class ){
diag_logger.log(
"AEMonSem: mid = " + monitor_id_next +
", sid = " + semaphore_id_next +
", monitors = " + debug_monitors.size() +
", semaphores = " + debug_semaphores.size() +
", names = " + debug_name_mapping.size() +
", traces = " + debug_traces.size());
Iterator it = debug_monitors.keySet().iterator();
long new_mon_entries = 0;
while (it.hasNext()){
AEMonitor monitor = (AEMonitor)it.next();
long diff = monitor.entry_count - monitor.last_entry_count;
if ( diff != 0 ){
active.add( monitor );
new_mon_entries += diff;
}
if (monitor.waiting > 0 ){
waiting_monitors.add( monitor );
}else if ( monitor.owner != null ){
busy_monitors.add( monitor );
}
}
it = debug_semaphores.keySet().iterator();
long new_sem_entries = 0;
while (it.hasNext()){
AEMonSem semaphore = (AEMonSem)it.next();
long diff = semaphore.entry_count - semaphore.last_entry_count;
if ( diff != 0 ){
active.add( semaphore );
new_sem_entries += diff;
}
if (semaphore.waiting > 0 ){
waiting_semaphores.add( semaphore );
}
}
diag_logger.log(
" activity: monitors = " + new_mon_entries + " - " + (new_mon_entries / (DEBUG_TIMER/1000)) +
"/sec, semaphores = " + new_sem_entries + " - " +
(new_sem_entries / (DEBUG_TIMER/1000)) + "/sec ");
}
AEMonSem[] x = new AEMonSem[active.size()];
active.toArray(x);
// sort by name and merge values
Arrays.sort(
x,
new Comparator()
{
public int
compare(
Object o1,
Object o2 )
{
AEMonSem a1 = (AEMonSem)o1;
AEMonSem a2 = (AEMonSem)o2;
return( a1.name.compareTo( a2.name ));
}
});
AEMonSem current = null;
long current_total = 0;
Object[][] total_x = new Object[x.length][];
int total_pos = 0;
for (int i=0;i<x.length;i++){
AEMonSem ms = x[i];
long diff = ms.entry_count - ms.last_entry_count;
if ( current == null ){
current = ms;
}else{
if( current.name.equals( ms.name )){
current_total += diff;
}else{
total_x[total_pos++] = new Object[]{ current.name, new Long( current_total )};
current = ms;
current_total = diff;
}
}
}
if (current != null ){
total_x[total_pos++] = new Object[]{ current.name, new Long( current_total )};
}
Arrays.sort(
total_x,
new Comparator()
{
public int
compare(
Object o1,
Object o2 )
{
Object[] a1 = (Object[])o1;
Object[] a2 = (Object[])o2;
if ( a1 == null && a2 == null){
return(0);
}else if ( a1 == null ){
return( 1 );
}else if ( a2 == null ){
return( -1 );
}
long a1_count = ((Long)a1[1]).longValue();
long a2_count = ((Long)a2[1]).longValue();
return((int)(a2_count - a1_count ));
}
});
String top_act_str = " top activity: ";
for (int i=0;i<Math.min(10,total_x.length);i++){
if ( total_x[i] != null ){
top_act_str += (i==0?"":", ") + total_x[i][0] + " = " + (total_x[i][1]);
}
}
diag_logger.log( top_act_str );
if ( waiting_monitors.size() > 0 ){
diag_logger.log( " waiting monitors" );
for (int i=0;i<waiting_monitors.size();i++){
AEMonSem ms = (AEMonSem)waiting_monitors.get(i);
Thread last_waiter = ((AEMonitor)ms).last_waiter;
diag_logger.log( " [" + (last_waiter==null?"<waiter lost>":last_waiter.getName()) + "] " + ms.name + " - " + ms.last_trace_key );
}
}
if ( busy_monitors.size() > 0 ){
diag_logger.log( " busy monitors" );
for (int i=0;i<busy_monitors.size();i++){
AEMonSem ms = (AEMonSem)busy_monitors.get(i);
Thread owner = ((AEMonitor)ms).owner;
diag_logger.log( " [" + (owner==null?"<owner lost>":owner.getName()) + "] " + ms.name + " - " + ms.last_trace_key );
}
}
if ( waiting_semaphores.size() > 0 ){
diag_logger.log( " waiting semaphores" );
for (int i=0;i<waiting_semaphores.size();i++){
AEMonSem ms = (AEMonSem)waiting_semaphores.get(i);
Thread last_waiter = ((AESemaphore)ms).latest_waiter;
diag_logger.log( " [" + (last_waiter==null?"<waiter lost>":last_waiter.getName()) + "] " + ms.name + " - " + ms.last_trace_key );
}
}
for (int i=0;i<x.length;i++){
AEMonSem ms = x[i];
ms.last_entry_count = ms.entry_count;
}
}
protected long entry_count;
protected long last_entry_count;
protected String last_trace_key;
protected String name;
protected boolean is_monitor;
protected int waiting = 0;
// protected boolean trace;
protected
AEMonSem(
String _name,
boolean _monitor )
{
is_monitor = _monitor;
if ( is_monitor) {
name = _name;
}else{
name = "(S)" + _name;
}
if ( DEBUG ){
synchronized( AEMonSem.class ){
if ( is_monitor ){
monitor_id_next++;
}else{
semaphore_id_next++;
}
StackTraceElement elt = new Exception().getStackTrace()[2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -