public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* Writing tapset functions for multiple versions
       [not found] <64396010.22700492.1468961291108.JavaMail.zimbra@redhat.com>
@ 2016-07-19 21:06 ` Felix Lu
  2016-07-20 14:05   ` David Smith
  0 siblings, 1 reply; 7+ messages in thread
From: Felix Lu @ 2016-07-19 21:06 UTC (permalink / raw)
  To: systemtap

This is a demonstration of writing functions for multiple
versions of a tapset.

Consider the scenario where multiple tapsets are installed, each targeting
a different version of some process/library. You might want to provide a
function f that is implemented differently for each version. It is possible
to create the functions f1 and f2, but this means that the users
can't create portable scripts that work with all versions. This can now
be done with function overloading in systemtap 3.0.

# version1.stp
function f() {
  if (pp() !~ "version1")
    next
  println("version1")
}
probe pp = process("version1/process").function("main") {}

# version2.stp
function f() {
  if (pp() !~ "version2")
    next
  println("version2")
}
probe pp = process("version2/process").function("main") {}

$ stap -I . -e 'probe pp {f()}' -c ./version1/process 
version1

$ stap -I . -e 'probe pp {f()}' -c ./version2/process
version2

Based on the context of the probe, the correct function
is selected at run time.

The condition to select an overloaded function can be
arbitrary. In this case, we check the probe point that is triggered.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Writing tapset functions for multiple versions
  2016-07-19 21:06 ` Writing tapset functions for multiple versions Felix Lu
@ 2016-07-20 14:05   ` David Smith
  2016-07-20 14:47     ` Felix Lu
  0 siblings, 1 reply; 7+ messages in thread
From: David Smith @ 2016-07-20 14:05 UTC (permalink / raw)
  To: Felix Lu, systemtap

On 07/19/2016 04:06 PM, Felix Lu wrote:
> This is a demonstration of writing functions for multiple
> versions of a tapset.
> 
> Consider the scenario where multiple tapsets are installed, each targeting
> a different version of some process/library. You might want to provide a
> function f that is implemented differently for each version. It is possible
> to create the functions f1 and f2, but this means that the users
> can't create portable scripts that work with all versions. This can now
> be done with function overloading in systemtap 3.0.
> 
> # version1.stp
> function f() {
>   if (pp() !~ "version1")
>     next
>   println("version1")
> }
> probe pp = process("version1/process").function("main") {}
> 
> # version2.stp
> function f() {
>   if (pp() !~ "version2")
>     next
>   println("version2")
> }
> probe pp = process("version2/process").function("main") {}
> 
> $ stap -I . -e 'probe pp {f()}' -c ./version1/process 
> version1
> 
> $ stap -I . -e 'probe pp {f()}' -c ./version2/process
> version2
> 
> Based on the context of the probe, the correct function
> is selected at run time.
> 
> The condition to select an overloaded function can be
> arbitrary. In this case, we check the probe point that is triggered.

(One confusing thing about your example above is that you are using the
'pp' function, but you also have a probe called 'pp'. I think your
example would be clearer if you renamed your probe.)

I'm worried about overhead here. If you have to do that string
comparison in every function, it seems like that would only work for a
small tapset. If you've got a large tapset (or a tapset function that
calls another tapset function in a loop), that overhead is going to add
up. One way to lower to overhead would be to have a set of public
functions that do the pp() check, which are basically wrappers around
private functions that don't.

Are there other ways to lower the overhead? Could each probe set a
global indexed by tid() to some value? (Or by that point would the
string comparison you are using be about the same?)

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Writing tapset functions for multiple versions
  2016-07-20 14:05   ` David Smith
@ 2016-07-20 14:47     ` Felix Lu
  2016-07-20 15:04       ` David Smith
  0 siblings, 1 reply; 7+ messages in thread
From: Felix Lu @ 2016-07-20 14:47 UTC (permalink / raw)
  To: David Smith; +Cc: systemtap





----- Original Message -----
> From: "David Smith" <dsmith@redhat.com>
> To: "Felix Lu" <flu@redhat.com>, systemtap@sourceware.org
> Sent: Wednesday, 20 July, 2016 10:05:09 AM
> Subject: Re: Writing tapset functions for multiple versions
> 
> On 07/19/2016 04:06 PM, Felix Lu wrote:
> > This is a demonstration of writing functions for multiple
> > versions of a tapset.
> > 
> > Consider the scenario where multiple tapsets are installed, each targeting
> > a different version of some process/library. You might want to provide a
> > function f that is implemented differently for each version. It is possible
> > to create the functions f1 and f2, but this means that the users
> > can't create portable scripts that work with all versions. This can now
> > be done with function overloading in systemtap 3.0.
> > 
> > # version1.stp
> > function f() {
> >   if (pp() !~ "version1")
> >     next
> >   println("version1")
> > }
> > probe pp = process("version1/process").function("main") {}
> > 
> > # version2.stp
> > function f() {
> >   if (pp() !~ "version2")
> >     next
> >   println("version2")
> > }
> > probe pp = process("version2/process").function("main") {}
> > 
> > $ stap -I . -e 'probe pp {f()}' -c ./version1/process
> > version1
> > 
> > $ stap -I . -e 'probe pp {f()}' -c ./version2/process
> > version2
> > 
> > Based on the context of the probe, the correct function
> > is selected at run time.
> > 
> > The condition to select an overloaded function can be
> > arbitrary. In this case, we check the probe point that is triggered.
> 
> (One confusing thing about your example above is that you are using the
> 'pp' function, but you also have a probe called 'pp'. I think your
> example would be clearer if you renamed your probe.)
> 
> I'm worried about overhead here. If you have to do that string
> comparison in every function, it seems like that would only work for a
> small tapset. If you've got a large tapset (or a tapset function that
> calls another tapset function in a loop), that overhead is going to add
> up. One way to lower to overhead would be to have a set of public
> functions that do the pp() check, which are basically wrappers around
> private functions that don't.
> 
> Are there other ways to lower the overhead? Could each probe set a
> global indexed by tid() to some value? (Or by that point would the
> string comparison you are using be about the same?)

A global integer instead of the string comparison could be set if you
are worried about the overhead. In the example above, tid() could be
saved in the probe alias body as a private global which would be sufficient
for identifying the desired function.  

> 
> --
> David Smith
> dsmith@redhat.com
> Red Hat
> http://www.redhat.com
> 256.217.0141 (direct)
> 256.837.0057 (fax)
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Writing tapset functions for multiple versions
  2016-07-20 14:47     ` Felix Lu
@ 2016-07-20 15:04       ` David Smith
  2016-07-20 15:25         ` Felix Lu
  0 siblings, 1 reply; 7+ messages in thread
From: David Smith @ 2016-07-20 15:04 UTC (permalink / raw)
  To: Felix Lu; +Cc: systemtap

On 07/20/2016 09:47 AM, Felix Lu wrote:

>> Are there other ways to lower the overhead? Could each probe set a
>> global indexed by tid() to some value? (Or by that point would the
>> string comparison you are using be about the same?)
> 
> A global integer instead of the string comparison could be set if you
> are worried about the overhead. In the example above, tid() could be
> saved in the probe alias body as a private global which would be sufficient
> for identifying the desired function.  

I'm not quite sure how saving tid() in a private global would work if
you are probing more than one thread at a time. Or did I misunderstand
your idea and your global is an array? If the private global is an
array, now we've got 2 private global arrays (1 for version1.stp and 1
for version2.stp).

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Writing tapset functions for multiple versions
  2016-07-20 15:04       ` David Smith
@ 2016-07-20 15:25         ` Felix Lu
  2016-07-20 16:23           ` Felix Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Felix Lu @ 2016-07-20 15:25 UTC (permalink / raw)
  To: David Smith; +Cc: systemtap


> > A global integer instead of the string comparison could be set if you
> > are worried about the overhead. In the example above, tid() could be
> > saved in the probe alias body as a private global which would be sufficient
> > for identifying the desired function.
> 
> I'm not quite sure how saving tid() in a private global would work if
> you are probing more than one thread at a time. Or did I misunderstand
> your idea and your global is an array? If the private global is an
> array, now we've got 2 private global arrays (1 for version1.stp and 1
> for version2.stp).

A global scalar should suffice in this case. All we want is for the function
f in version1.stp to be called when version1/process is executed and likewise
for version2. The probe alias body in the above example would update the saved
tid() every time it's hit.

> 
> --
> David Smith
> dsmith@redhat.com
> Red Hat
> http://www.redhat.com
> 256.217.0141 (direct)
> 256.837.0057 (fax)
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Writing tapset functions for multiple versions
  2016-07-20 15:25         ` Felix Lu
@ 2016-07-20 16:23           ` Felix Lu
  2016-07-20 16:38             ` Josh Stone
  0 siblings, 1 reply; 7+ messages in thread
From: Felix Lu @ 2016-07-20 16:23 UTC (permalink / raw)
  To: David Smith; +Cc: systemtap


> > > A global integer instead of the string comparison could be set if you
> > > are worried about the overhead. In the example above, tid() could be
> > > saved in the probe alias body as a private global which would be
> > > sufficient
> > > for identifying the desired function.
> > 
> > I'm not quite sure how saving tid() in a private global would work if
> > you are probing more than one thread at a time. Or did I misunderstand
> > your idea and your global is an array? If the private global is an
> > array, now we've got 2 private global arrays (1 for version1.stp and 1
> > for version2.stp).
> 
> A global scalar should suffice in this case. All we want is for the function
> f in version1.stp to be called when version1/process is executed and likewise
> for version2. The probe alias body in the above example would update the
> saved
> tid() every time it's hit.

Using a saved global may not be more efficient than the pp() regex comparison.
Systemtap global variables are locked upon probe handler entry. By updating
the saved tid(), an exclusive lock must be obtained. The overhead from this
may be greater than the string matching.  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Writing tapset functions for multiple versions
  2016-07-20 16:23           ` Felix Lu
@ 2016-07-20 16:38             ` Josh Stone
  0 siblings, 0 replies; 7+ messages in thread
From: Josh Stone @ 2016-07-20 16:38 UTC (permalink / raw)
  To: systemtap

On 07/20/2016 09:23 AM, Felix Lu wrote:
> 
>>>> A global integer instead of the string comparison could be set if you
>>>> are worried about the overhead. In the example above, tid() could be
>>>> saved in the probe alias body as a private global which would be
>>>> sufficient
>>>> for identifying the desired function.
>>>
>>> I'm not quite sure how saving tid() in a private global would work if
>>> you are probing more than one thread at a time. Or did I misunderstand
>>> your idea and your global is an array? If the private global is an
>>> array, now we've got 2 private global arrays (1 for version1.stp and 1
>>> for version2.stp).
>>
>> A global scalar should suffice in this case. All we want is for the function
>> f in version1.stp to be called when version1/process is executed and likewise
>> for version2. The probe alias body in the above example would update the
>> saved
>> tid() every time it's hit.

A scalar implies that there is only one such target at a given time.
Furthermore, if you use tid() that implies you only care about one
particular thread, where at least pid() would cover a whole process.

These may be acceptable choices for a user's script, but our tapsets
should be prepared to run with many process targets at once.

> Using a saved global may not be more efficient than the pp() regex comparison.
> Systemtap global variables are locked upon probe handler entry. By updating
> the saved tid(), an exclusive lock must be obtained. The overhead from this
> may be greater than the string matching.  

True, although if it's already locking any other variables, then this
particular lock might be overshadowed and always succeed anyway, which
is cheap.  (There's a bug to collapse these, PR10741.)


We can make lots of speculations, but if you're really concerned about
performance, you should directly measure and compare methods.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-07-20 16:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <64396010.22700492.1468961291108.JavaMail.zimbra@redhat.com>
2016-07-19 21:06 ` Writing tapset functions for multiple versions Felix Lu
2016-07-20 14:05   ` David Smith
2016-07-20 14:47     ` Felix Lu
2016-07-20 15:04       ` David Smith
2016-07-20 15:25         ` Felix Lu
2016-07-20 16:23           ` Felix Lu
2016-07-20 16:38             ` Josh Stone

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).