Based on my current limited understanding of NPTL, it does require NPTL
to be turned off because otherwise, all PIDs will be the same. If
sub-threads with NPTL have their on PIDs, then my usual incantation for
ps doesn't reveal them, so I wouldn't have something to look for the
thread for. I believe this code will likely return the same value for
every thread if used with NPTL turned on.
Matthew Toseland wrote:
> Does this require NPTL to be turned off? Do sub-threads have their own PIDs
> with NPTL?
>
> On Tuesday 28 August 2007 01:50, you wrote:
>
>> Author: zothar
>> Date: 2007-08-28 00:50:36 +0000 (Tue, 28 Aug 2007)
>> New Revision: 14897
>>
>> Added:
>> trunk/freenet/src/freenet/support/OSThread.java
>> Modified:
>> trunk/freenet/src/freenet/client/async/BackgroundBlockEncoder.java
>> Log:
>> Potential debugging tool: provide getPID() and logPID() to get or log the
>>
> thread's PID on Linux with /proc/self/stat available to the JVM (support
> could later be expanded with JNI or other methods). These tools are
> currently configured with static variables, are currently only configurable
> at compile time and are currently off.
>
>> Modified: trunk/freenet/src/freenet/client/async/BackgroundBlockEncoder.java
>> ===================================================================
>> --- trunk/freenet/src/freenet/client/async/BackgroundBlockEncoder.java
>>
> 2007-08-28 00:47:06 UTC (rev 14896)
>
>> +++ trunk/freenet/src/freenet/client/async/BackgroundBlockEncoder.java
>>
> 2007-08-28 00:50:36 UTC (rev 14897)
>
>> @@ -45,6 +45,7 @@
>> }
>>
>> public void run() {
>> + freenet.support.OSThread.logPID(this);
>> while(true) {
>> SingleBlockInserter sbi = null;
>> synchronized(this) {
>>
>> Added: trunk/freenet/src/freenet/support/OSThread.java
>> ===================================================================
>> --- trunk/freenet/src/freenet/support/OSThread.java
>>
> (rev 0)
>
>> +++ trunk/freenet/src/freenet/support/OSThread.java 2007-08-28 00:50:36 UTC
>>
> (rev 14897)
>
>> @@ -0,0 +1,208 @@
>> +/* This code is part of Freenet. It is distributed under the GNU General
>> + * Public License, version 2 (or at your option any later version). See
>> + * http://www.gnu.org/ for further details of the GPL. */
>> +package freenet.support;
>> +
>> +import java.io.File;
>> +import java.io.FileInputStream;
>> +import java.io.FileNotFoundException;
>> +import java.io.IOException;
>> +import java.util.regex.PatternSyntaxException;
>> +
>> +import freenet.support.Logger;
>> +
>> +/**
>> + * Get OS/Thread information using one or more methods
>> + */
>> +public class OSThread {
>> +
>> + public static boolean getPIDEnabled = false;
>> + public static boolean getPPIDEnabled = false;
>> + public static boolean procSelfStatEnabled = false;
>> +
>> + /**
>> + * Get the thread's process ID or return -1 if it's unavailable for
>>
> some reason
>
>> + */
>> + public synchronized static int getPID(Object o) {
>> + if(!getPIDEnabled) {
>> + return -1;
>> + }
>> + return getPIDFromProcSelfStat(o);
>> + }
>> +
>> + /**
>> + * Get the thread's parent process ID or return -1 if it's unavailable
>>
> for some reason
>
>> + */
>> + public synchronized static int getPPID(Object o) {
>> + if(!getPPIDEnabled) {
>> + return -1;
>> + }
>> + return getPPIDFromProcSelfStat(o);
>> + }
>> +
>> + /**
>> + * Get the thread's process ID using the /proc/self/stat method or
>> + * return -1 if it's unavailable for some reason. This is an ugly
>> + * hack required by Java to get the OS process ID of a thread on
>> + * Linux without using JNI.
>> + */
>> + public synchronized static int getPIDFromProcSelfStat(Object o) {
>> + StringBuffer sb = null;
>> + int b = -1;
>> + int pid = -1;
>> + String msg = null;
>> +
>> + if(!getPIDEnabled) {
>> + return -1;
>> + }
>> + if(!procSelfStatEnabled) {
>> + return -1;
>> + }
>> +
>> + // read /proc/self/stat and parse for the PID
>> + FileInputStream fis = null;
>> + File procFile = new File("/proc/self/stat");
>> + if(procFile.exists()) {
>> + try {
>> + fis = new FileInputStream(procFile);
>> + } catch (FileNotFoundException e1) {
>> + Logger.normal(o, "'/proc/self/stat' not found");
>> + fis = null;
>> + }
>> + if(null != fis) {
>> + sb = new StringBuffer();
>> + while( true ) {
>> + try {
>> + b = fis.read();
>> + } catch (IOException e) {
>> + Logger.error(o, "Caught
>> IOException in fis.read() of
>>
> OSThread.getPIDFromProcSelfStat()", e);
>
>> + b = -1;
>> + }
>> + if( -1 == b ) {
>> + break;
>> + }
>> + sb.append( (char) b );
>> + }
>> + try {
>> + msg = "DEBUG: Gonna parse
>> ["+sb.toString()+"]";
>> + System.out.println(msg + ": " + o);
>> + Logger.normal(o, msg);
>> + String[] procStrings =
>> sb.toString().trim().split(" ");
>> + if(4 <= procStrings.length) {
>> + String pidString = procStrings[
>> 0 ];
>> + try {
>> + pid = Integer.parseInt(
>> pidString.trim() );
>> + } catch (NumberFormatException
>> e) {
>> + Logger.error(o, "Caught
>> NumberFormatException in Integer.parseInt()
>>
> of OSThread.getPIDFromProcSelfStat() while parsing '"+pidString+"'", e);
>
>> + }
>> + }
>> + } catch (PatternSyntaxException e) {
>> + Logger.error(o, "Caught
>> PatternSyntaxException in
>>
> sb.toString().trim().split(\" \") of OSThread.getPIDFromProcSelfStat() while
> parsing '"+sb.toString()+"'", e);
>
>> + }
>> + }
>> + }
>> + return pid;
>> + }
>> +
>> + /**
>> + * Get the thread's parent process ID using the /proc/self/stat
>> + * method or return -1 if it's unavailable for some reason. This
>> + * is ugly hack required by Java to get the OS parent process ID of
>> + * a thread on Linux without using JNI.
>> + */
>> + public synchronized static int getPPIDFromProcSelfStat(Object o) {
>> + StringBuffer sb = null;
>> + int b = -1;
>> + int ppid = -1;
>> + String msg = null;
>> +
>> + if(!getPPIDEnabled) {
>> + return -1;
>> + }
>> + if(!procSelfStatEnabled) {
>> + return -1;
>> + }
>> +
>> + // read /proc/self/stat and parse for the PPID
>> + FileInputStream fis = null;
>> + File procFile = new File("/proc/self/stat");
>> + if(procFile.exists()) {
>> + try {
>> + fis = new FileInputStream(procFile);
>> + } catch (FileNotFoundException e1) {
>> + Logger.normal(o, "'/proc/self/stat' not found");
>> + fis = null;
>> + }
>> + if(null != fis) {
>> + sb = new StringBuffer();
>> + while( true ) {
>> + try {
>> + b = fis.read();
>> + } catch (IOException e) {
>> + Logger.error(o, "Caught
>> IOException in fis.read() of
>>
> OSThread.getPPIDFromProcSelfStat()", e);
>
>> + b = -1;
>> + }
>> + if( -1 == b ) {
>> + break;
>> + }
>> + sb.append( (char) b );
>> + }
>> + try {
>> + msg = "DEBUG: Gonna parse
>> ["+sb.toString()+"]";
>> + System.out.println(msg + ": " + o);
>> + Logger.normal(o, msg);
>> + String[] procStrings =
>> sb.toString().trim().split(" ");
>> + if(4 <= procStrings.length) {
>> + String ppidString =
>> procStrings[ 3 ];
>> + try {
>> + ppid =
>> Integer.parseInt( ppidString.trim() );
>> + } catch (NumberFormatException
>> e) {
>> + Logger.error(o, "Caught
>> NumberFormatException in Integer.parseInt()
>>
> of OSThread.getPPIDFromProcSelfStat() while parsing '"+ppidString+"'", e);
>
>> + }
>> + }
>> + } catch (PatternSyntaxException e) {
>> + Logger.error(o, "Caught
>> PatternSyntaxException in
>>
> sb.toString().trim().split(\" \") of OSThread.getPPIDFromProcSelfStat() while
> parsing '"+sb.toString()+"'", e);
>
>> + }
>> + }
>> + }
>> + return ppid;
>> + }
>> +
>> + /**
>> + * Log the thread's process ID or return -1 if it's unavailable for
>>
> some reason
>
>> + */
>> + public synchronized static int logPID(Object o) {
>> + if(!getPIDEnabled) {
>> + return -1;
>> + }
>> + int pid = getPID(o);
>> + String msg;
>> + if(-1 != pid) {
>> + msg = "This thread's OS PID is " + pid;
>> + } else {
>> + msg = "This thread's OS PID could not be determined";
>> + }
>> + System.out.println(msg + ": " + o);
>> + Logger.normal(o, msg);
>> + return pid;
>> + }
>> +
>> + /**
>> + * Log the thread's process ID or return -1 if it's unavailable for
>>
> some reason
>
>> + */
>> + public synchronized static int logPPID(Object o) {
>> + if(!getPPIDEnabled) {
>> + return -1;
>> + }
>> + int ppid = getPPID(o);
>> + String msg;
>> + if(-1 != ppid) {
>> + msg = "This thread's OS PPID is " + ppid;
>> + } else {
>> + msg = "This thread's OS PPID could not be determined";
>> + }
>> + System.out.println(msg + ": "+o);
>> + Logger.normal(o, msg);
>> + return ppid;
>> + }
>> +}
>>