[lldb-dev] Use of thread local storage in Timer
Zachary Turner
zturner at google.com
Mon Sep 8 14:12:58 PDT 2014
Anyway, you mentioned that it needs to work for threads other than those
created explicitly by us, so this approach doesn't work regardless.
On Mon, Sep 8, 2014 at 2:11 PM, Zachary Turner <zturner at google.com> wrote:
> No, what I'm saying is that if the thread routine returns normally and is
> not cancelled, you can just explicitly call the "destructor" at the end of
> the thread routine. You don't need the OS to do it for you.
>
>
> On Mon, Sep 8, 2014 at 1:13 PM, Greg Clayton <gclayton at apple.com> wrote:
>
>>
>> > On Sep 8, 2014, at 11:27 AM, Zachary Turner <zturner at google.com> wrote:
>> >
>> > On Mon, Sep 8, 2014 at 10:39 AM, Greg Clayton <gclayton at apple.com>
>> wrote:
>> >
>> >>
>> >> This would solve the portability issue since TLS destructors would no
>> longer be needed, and making porting all of our TLS code to use llvm
>> support libraries very easy.
>> >>
>> >> Does this assessment seem correct? Or am I missing something?
>> >
>> > The idea is you can place a "Timer" object anywhere in code and it can
>> some profiling by timing how long it takes. If another function makes
>> another "Timer" object, it will push itself on the stack, stop the previous
>> timer, wait until it destroys itself and pop itself back off the stack,
>> keep a long running total time spent doing the task, and then reactivate
>> the timer above it.
>> >
>> > So the TLS destructor are currently required. If TLS destructors aren't
>> supported on the platform, then this class should be disabled for that
>> platform (hollow it out and have it do nothing for platforms that don't
>> support it).
>> >
>> > Greg
>> >
>> > It sounds like you're talking about getting a function's exclusive
>> time? As in, if function A calls B, and you create a timer in both A and
>> B, then the timer in A will compute timeof(A) - timeof(B)?
>>
>> It is timing from Timer construction time, to Timer destruction time, and
>> keeping a global map of all timer times using the constructors first string
>> value as a ConstString as the key. It does this on from all threads.
>>
>> > If not, and if it's sufficient to just time functions from start to end
>> along with all the child functions that execute, then llvm also has its own
>> timer class that we could use. See llvm/Support/Timer.h.
>>
>> That just implements timing, not aggregation and history of total times.
>>
>> >
>> > As for the TLS destructors, it seems this is only necessary in the case
>> that a thread is cancelled?
>>
>> Why? You create a thread, it call some function that invokes a timer:
>>
>> int foo()
>> {
>> {
>> Timer a("parse something within foo", ...);
>> bar();
>> }
>>
>> {
>> Timer a("parse something else within foo", ...);
>> bar();
>> }
>> }
>>
>> Then in bar you have:
>>
>> int bar()
>> {
>> Timer a("::bar()", ...);
>> }
>>
>> Any time a timer is constructed, it needs to get the TimerStack for the
>> current thread. It then pushes itself onto that stack and stops any other
>> timers already on that stack. When it destructs, it removes itself and
>> restarts the timers above. Total time spent and time between timers is kept
>> in a global repository where the key (the first string in the constructor)
>> is associated with the total and partial times.
>>
>> > Because if a thread routine runs to completion, we could just call
>> Timer::CleanupThreadSpecificData() or something.
>>
>> Then we need to guarantee every thread is created using our
>> Host::CreateThread() stuff so it can manage that. You can't guarantee that.
>> On MacOSX, somehow libdispatch() might get used and we don't control the
>> creation of those threads and they can call LLDB functions with contain
>> Timer objects.
>>
>> > Could we use pthread_cleanup_cancel() for the same purpose, and then
>> have our thread trampoline cleanup any timer-specific TLS data before it
>> returns to catch the non-cancellation case?
>>
>> I don't care how it happens, but the cleanup of deleting the TimerStack
>> for each thread must happen for any thread regardless of how it was started
>> (by us using Host::CreateThread(), or by the OS for any other reason).
>>
>> >
>> > My main concern is that I don't want to expose a generic thread-local
>> class that supports TLS destructors if TLS destructors aren't generic
>> enough to be available on all platforms. It makes it too easy to make use
>> of them in generic code, breaking other platforms.
>>
>> How can you have thread specific data on ANY platform without being able
>> to clean it up? Are we expected to only store integers and POD types in the
>> TLS data? That would surprise me very much if that is the case.
>>
>> Greg
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140908/7602b14f/attachment.html>
More information about the lldb-dev
mailing list