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; >> + } >> +} >>