Thead.parent, revisited. Or: Building a call stack.

Discussion in 'Ruby' started by Erik Veenstra, Mar 5, 2007.

  1. In order to build a diagram of all method calls in an
    application, I created a set_trace_func function. This function
    builds a call stack. Each thread in each process should have
    its own call stack, initialized to the call stack of the parent
    process or the parent thread.

    The call stacks are stored in the array stack_per_thread. The
    initial call stack is an empty array:

    stack_per_thread = []
    stack_per_thread[[Process.pid, Thread.current]] = []

    Creating a new call stack after a fork (both process fork and
    thread fork) is done like this:

    stack = (stack_per_thread[[Process.pid, Thread.current]] ||=
    stack.dup)

    Process forks are not a problem, since the last call stack
    before the process fork is the one with which the child process
    has to continue and does continue.

    However, threads are a bit of a problem. Threads don't have a
    parent, which means that it's not possible to clone the call
    stack of the parent thread. I currently fake the concept
    "parent thread" by assuming that the last running thread is the
    parent thread.

    If Parent.thread existed, everything would be perfectly fine:

    stack = (stack_per_thread[[Process.pid, Thread.current]] ||=
    stack_per_thread[[Process.pid, Thread.parent]].dup)

    I observed a couple of traces and noticed, empirically, that a
    new thread always gets a couple of CPU cycles (and hence calls
    to set_trace_func). If this is always true, my assumption ("the
    last thread is the parent thread") is no problem. If the parent
    process can spawn many threads before any of them gets some CPU
    cycles, well, then we do have a problem... :{

    Ideas? Related work? Anybody able to understand the C code?
    Matz?... :}

    gegroet,
    Erik V. - http://www.erikveen.dds.nl/
     
    Erik Veenstra, Mar 5, 2007
    #1
    1. Advertising

  2. Erik Veenstra

    Guest

    On Tue, 6 Mar 2007, Erik Veenstra wrote:

    > In order to build a diagram of all method calls in an
    > application, I created a set_trace_func function. This function
    > builds a call stack. Each thread in each process should have
    > its own call stack, initialized to the call stack of the parent
    > process or the parent thread.
    >
    > The call stacks are stored in the array stack_per_thread. The
    > initial call stack is an empty array:
    >
    > stack_per_thread = []
    > stack_per_thread[[Process.pid, Thread.current]] = []
    >
    > Creating a new call stack after a fork (both process fork and
    > thread fork) is done like this:
    >
    > stack = (stack_per_thread[[Process.pid, Thread.current]] ||=
    > stack.dup)
    >
    > Process forks are not a problem, since the last call stack
    > before the process fork is the one with which the child process
    > has to continue and does continue.
    >
    > However, threads are a bit of a problem. Threads don't have a
    > parent, which means that it's not possible to clone the call
    > stack of the parent thread. I currently fake the concept
    > "parent thread" by assuming that the last running thread is the
    > parent thread.
    >
    > If Parent.thread existed, everything would be perfectly fine:
    >
    > stack = (stack_per_thread[[Process.pid, Thread.current]] ||=
    > stack_per_thread[[Process.pid, Thread.parent]].dup)
    >
    > I observed a couple of traces and noticed, empirically, that a
    > new thread always gets a couple of CPU cycles (and hence calls
    > to set_trace_func). If this is always true, my assumption ("the
    > last thread is the parent thread") is no problem. If the parent
    > process can spawn many threads before any of them gets some CPU
    > cycles, well, then we do have a problem... :{
    >
    > Ideas? Related work? Anybody able to understand the C code?
    > Matz?... :}


    class Thread
    class << self
    alias_method "__new__", "new"
    def new *a, &b
    child '__new__', *a, &b
    end
    alias_method "__start__", "start"
    def start *a, &b
    child '__start__', *a, &b
    end
    private
    def child as, *a, &b
    parent = Thread.current
    send(as, *a) do |*a|
    Thread.current.parent = parent
    b.call *a
    end
    end
    end
    def parent
    self['parent']
    end
    def parent= parent
    self['parent'] = parent
    end
    def ancestors
    return self['ancestors'] if self['ancestors']
    list = [t = self]
    while((t = t.parent))
    list << t
    end
    self['ancestors'] = list
    end
    end


    -a
    --
    be kind whenever possible... it is always possible.
    - the dalai lama
     
    , Mar 5, 2007
    #2
    1. Advertising

  3. Yep, I know. That's a "work around". But, as we've discussed
    before [1], it's not water tight.

    "Thread#start doesn't reuse Thread.new. Neither does
    rb_thread_create(), which is used in e.g. TK."

    Thanks.

    gegroet,
    Erik V. - http://www.erikveen.dds.nl/

    [1] http://tinyurl.com/38823g
     
    Erik Veenstra, Mar 5, 2007
    #3
  4. Erik Veenstra

    Guest

    On Tue, 6 Mar 2007, Erik Veenstra wrote:

    > Yep, I know. That's a "work around". But, as we've discussed
    > before [1], it's not water tight.
    >
    > "Thread#start doesn't reuse Thread.new. Neither does
    > rb_thread_create(), which is used in e.g. TK."


    oh right. forgot.

    check out ThreadGroup - i think it's properties may allow someone to hack what
    you're after. just looking at that today - but out of time now...

    -a
    --
    be kind whenever possible... it is always possible.
    - the dalai lama
     
    , Mar 5, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David L

    thead in datagrid

    David L, Jul 29, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    504
    S. Justin Gengo
    Jul 29, 2003
  2. Christian Schmidt

    finishing a thead

    Christian Schmidt, Aug 21, 2003, in forum: Java
    Replies:
    3
    Views:
    769
    Adam Maass
    Aug 25, 2003
  3. Bram de Jong

    Any browser implementing THEAD?

    Bram de Jong, Nov 25, 2003, in forum: HTML
    Replies:
    11
    Views:
    744
    Mark Parnell
    Dec 1, 2003
  4. Woolly Mittens
    Replies:
    11
    Views:
    2,359
    William Tasso
    Jan 2, 2004
  5. Steve Jorgensen
    Replies:
    4
    Views:
    438
    Soren Kuula
    Aug 28, 2005
Loading...

Share This Page