📄 aemonsem.java
字号:
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: AEMonSem.java
package org.gudy.azureus2.core3.util;
import java.util.*;
// Referenced classes of package org.gudy.azureus2.core3.util:
// AEDiagnosticsLogger, AEMonitor, AESemaphore, Debug,
// StringInterner, Timer, TimerEventPerformer, AEDiagnostics,
// TimerEvent
public abstract class AEMonSem
{
protected static class monSemData
{
protected String class_name;
protected int line_number;
protected monSemData(String _class_name, int _line_number)
{
class_name = _class_name;
line_number = _line_number;
}
}
protected static boolean DEBUG;
protected static boolean DEBUG_CHECK_DUPLICATES = false;
protected static long DEBUG_TIMER = 30000L;
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 Map debug_name_mapping = new WeakHashMap();
private static Map debug_monitors = new WeakHashMap();
private static Map debug_semaphores = new WeakHashMap();
protected long entry_count;
protected long last_entry_count;
protected String last_trace_key;
protected String name;
protected boolean is_monitor;
protected int waiting;
protected static void check(AEDiagnosticsLogger diag_logger)
{
List active = new ArrayList();
List waiting_monitors = new ArrayList();
List busy_monitors = new ArrayList();
List waiting_semaphores = new ArrayList();
synchronized (org/gudy/azureus2/core3/util/AEMonSem)
{
diag_logger.log((new StringBuilder()).append("AEMonSem: mid = ").append(monitor_id_next).append(", sid = ").append(semaphore_id_next).append(", monitors = ").append(debug_monitors.size()).append(", semaphores = ").append(debug_semaphores.size()).append(", names = ").append(debug_name_mapping.size()).append(", traces = ").append(debug_traces.size()).toString());
Iterator it = debug_monitors.keySet().iterator();
long new_mon_entries = 0L;
do
{
if (!it.hasNext())
break;
AEMonitor monitor = (AEMonitor)it.next();
long diff = monitor.entry_count - monitor.last_entry_count;
if (diff != 0L)
{
active.add(monitor);
new_mon_entries += diff;
}
if (monitor.waiting > 0)
waiting_monitors.add(monitor);
else
if (monitor.owner != null)
busy_monitors.add(monitor);
} while (true);
it = debug_semaphores.keySet().iterator();
long new_sem_entries = 0L;
do
{
if (!it.hasNext())
break;
AEMonSem semaphore = (AEMonSem)it.next();
long diff = semaphore.entry_count - semaphore.last_entry_count;
if (diff != 0L)
{
active.add(semaphore);
new_sem_entries += diff;
}
if (semaphore.waiting > 0)
waiting_semaphores.add(semaphore);
} while (true);
diag_logger.log((new StringBuilder()).append(" activity: monitors = ").append(new_mon_entries).append(" - ").append(new_mon_entries / (DEBUG_TIMER / 1000L)).append("/sec, semaphores = ").append(new_sem_entries).append(" - ").append(new_sem_entries / (DEBUG_TIMER / 1000L)).append("/sec ").toString());
}
AEMonSem x[] = new AEMonSem[active.size()];
active.toArray(x);
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 = 0L;
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;
continue;
}
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(((Object []) (total_x)), new Comparator() {
public int compare(Object o1, Object o2)
{
Object a1[] = (Object[])(Object[])o1;
Object a2[] = (Object[])(Object[])o2;
if (a1 == null && a2 == null)
return 0;
if (a1 == null)
return 1;
if (a2 == null)
{
return -1;
} else
{
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 = (new StringBuilder()).append(top_act_str).append(i != 0 ? ", " : "").append(total_x[i][0]).append(" = ").append(total_x[i][1]).toString();
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((new StringBuilder()).append(" [").append(last_waiter != null ? last_waiter.getName() : "<waiter lost>").append("] ").append(ms.name).append(" - ").append(ms.last_trace_key).toString());
}
}
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((new StringBuilder()).append(" [").append(owner != null ? owner.getName() : "<owner lost>").append("] ").append(ms.name).append(" - ").append(ms.last_trace_key).toString());
}
}
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((new StringBuilder()).append(" [").append(last_waiter != null ? last_waiter.getName() : "<waiter lost>").append("] ").append(ms.name).append(" - ").append(ms.last_trace_key).toString());
}
}
for (int i = 0; i < x.length; i++)
{
AEMonSem ms = x[i];
ms.last_entry_count = ms.entry_count;
}
}
protected AEMonSem(String _name, boolean _monitor)
{
waiting = 0;
is_monitor = _monitor;
if (is_monitor)
name = _name;
else
name = StringInterner.intern((new StringBuilder()).append("(S)").append(_name).toString());
if (DEBUG)
synchronized (org/gudy/azureus2/core3/util/AEMonSem)
{
if (is_monitor)
monitor_id_next++;
else
semaphore_id_next++;
StackTraceElement elt = (new Exception()).getStackTrace()[2];
String class_name = elt.getClassName();
int line_number = elt.getLineNumber();
monSemData new_entry = new monSemData(class_name, line_number);
if (is_monitor)
debug_monitors.put(this, new_entry);
else
debug_semaphores.put(this, new_entry);
if (DEBUG_CHECK_DUPLICATES)
{
monSemData existing_name_entry = (monSemData)debug_name_mapping.get(name);
if (existing_name_entry == null)
debug_name_mapping.put(name, new_entry);
else
if (!existing_name_entry.class_name.equals(class_name) || existing_name_entry.line_number != line_number)
Debug.out(new Exception((new StringBuilder()).append("Duplicate AEMonSem name '").append(name).append("'").toString()));
}
}
}
protected void debugEntry()
{
try
{
Stack stack = (Stack)tls.get();
if (stack.size() > 64)
{
StringBuffer sb = new StringBuffer(1024);
for (int i = 0; i < stack.size(); i++)
{
AEMonSem mon = (AEMonSem)stack.get(i);
sb.append((new StringBuilder()).append("$").append(mon.name).toString());
}
Debug.out((new StringBuilder()).append("**** Whoaaaaaa, AEMonSem debug stack is getting too large!!!! **** ").append(sb).toString());
}
if (!stack.isEmpty())
{
String recursion_trace = "";
StringBuffer sb = new StringBuffer();
boolean check_recursion = is_monitor && !debug_recursions.contains(name);
String prev_name = null;
for (int i = 0; i < stack.size(); i++)
{
AEMonSem mon = (AEMonSem)stack.get(i);
if (check_recursion && mon.name.equals(name) && mon != this)
{
recursion_trace = (new StringBuilder()).append(recursion_trace).append(recursion_trace.length() != 0 ? "\r\n" : "").append("Recursive locks on different instances: ").append(name).toString();
debug_recursions.add(name);
}
if (prev_name == null || !mon.name.equals(prev_name))
{
sb.append("$");
sb.append(mon.name);
}
prev_name = mon.name;
}
sb.append("$");
sb.append(name);
sb.append("$");
String trace_key = sb.toString();
if (recursion_trace.length() > 0)
Debug.outNoStack((new StringBuilder()).append(recursion_trace).append("\r\n ").append(trace_key).toString());
last_trace_key = trace_key;
if (!is_monitor)
{
boolean match = false;
int i = 0;
do
{
if (i >= stack.size())
break;
AEMonSem ms = (AEMonSem)stack.get(i);
if (ms.name.equals(name))
{
match = true;
break;
}
i++;
} while (true);
if (!match)
stack.push(this);
} else
{
stack.push(this);
}
synchronized (debug_traces)
{
if (debug_traces.get(trace_key) == null)
{
Thread thread = Thread.currentThread();
String thread_name = (new StringBuilder()).append(thread.getName()).append("[").append(thread.hashCode()).append("]").toString();
String stack_trace = Debug.getStackTrace(true, false);
Iterator it = debug_traces.keySet().iterator();
do
{
if (!it.hasNext())
break;
String old_key = (String)it.next();
String data[] = (String[])(String[])debug_traces.get(old_key);
String old_thread_name = data[0];
String old_trace = data[1];
if (!thread_name.equals(old_thread_name))
{
int earliest_common = stack.size();
int common_count = 0;
for (int i = 0; i < stack.size(); i++)
{
String n1 = ((AEMonSem)stack.get(i)).name;
int p1 = old_key.indexOf((new StringBuilder()).append("$").append(n1).append("$").toString());
if (p1 != -1)
{
common_count++;
earliest_common = Math.min(earliest_common, i + 1);
}
}
if (common_count >= 2)
{
int i = 0;
while (i < earliest_common)
{
AEMonSem ms1 = (AEMonSem)stack.get(i);
if (ms1.is_monitor)
{
String n1 = ms1.name;
for (int j = i + 1; j < stack.size(); j++)
{
AEMonSem ms2 = (AEMonSem)stack.get(j);
if (!ms2.is_monitor)
continue;
String n2 = ms2.name;
if (n1.equals(n2))
continue;
int p1 = old_key.indexOf((new StringBuilder()).append("$").append(n1).append("$").toString());
int p2 = old_key.indexOf((new StringBuilder()).append("$").append(n2).append("$").toString());
if (p1 == -1 || p2 == -1 || p1 <= p2)
continue;
String reciprocal_log = (new StringBuilder()).append(trace_key).append(" / ").append(old_key).toString();
if (!debug_reciprocals.contains(reciprocal_log))
{
debug_reciprocals.add(reciprocal_log);
Debug.outNoStack((new StringBuilder()).append("AEMonSem: Reciprocal usage:\r\n ").append(trace_key).append("\r\n").append(" [").append(thread_name).append("] ").append(stack_trace).append("\r\n").append(" ").append(old_key).append("\r\n").append(" [").append(old_thread_name).append("] ").append(old_trace).toString());
}
}
}
i++;
}
}
}
} while (true);
debug_traces.put(trace_key, new String[] {
thread_name, stack_trace
});
}
}
} else
{
last_trace_key = (new StringBuilder()).append("$").append(name).append("$").toString();
stack.push(this);
}
}
catch (Throwable e)
{
try
{
Debug.printStackTrace(e);
}
catch (Throwable f) { }
}
}
protected void debugExit()
{
try
{
Stack stack = (Stack)tls.get();
if (is_monitor)
{
for (; stack.peek() != this; stack.pop());
stack.pop();
} else
if (!stack.isEmpty() && stack.peek() == this)
stack.pop();
}
catch (Throwable e)
{
try
{
Debug.printStackTrace(e);
}
catch (Throwable f) { }
}
}
public String getName()
{
return name;
}
static
{
DEBUG = false;
if (DEBUG)
{
Thread t = new Thread("AEMonSem:delay debug init") {
public void run()
{
AEMonSem.debug_recursions.add("ResourceDownloader");
AEMonSem.debug_recursions.add("ConnectionPool:CP");
AEMonSem.debug_recursions.add("(S)RDRretry");
try
{
Thread.sleep(AEMonSem.DEBUG_TIMER);
}
catch (Throwable e) { }
TimerEventPerformer performer = new TimerEventPerformer() {
AEDiagnosticsLogger diag_logger;
final 2 this$0;
public void perform(TimerEvent event)
{
if (diag_logger == null)
diag_logger = AEDiagnostics.getLogger("monsem");
AEMonSem.check(diag_logger);
}
{
this$0 = 2.this;
super();
}
};
performer.perform(null);
(new Timer("AEMonSem")).addPeriodicEvent(AEMonSem.DEBUG_TIMER, performer);
}
};
t.setDaemon(true);
t.start();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -