Re: [lttng-dev] Test if tracepoint is enabled

2012-12-05 Thread David Bryant

On 05/12/12 20:49, Mathieu Desnoyers wrote:

* David Bryant (david.bry...@quantum.com) wrote:

So, building on your example:

#define tracepoint_cond(provider, name, pre, post, ...) \
 do { \
 if (caa_unlikely(__tracepoint_##provider##___##name.state)) { \
 pre \
 __tracepoint_cb_##provider##___##name(__VA_ARGS__); \
 post \
 } \
 } \
 while (0)

And a contrived example:

#include stdio.h
#include stdlib.h

int main() {
 char * a;
 tracepoint_cond(provider, name,
 { printf(pre\n);  a = malloc(16); },
 { printf(post\n); free(a);}
);
 return 0;
}

This is ok. But more work with the macro handling would be required to
get the pre/post code fragments through as parameters. The example only
compiles because its pre/post arguments don't contain any commas.

What do you think?

I'm not sure what parameters would cause issues with commas. If they are
between parenthesis or brackets, it should be fine. Do you have an
example perhaps ?
Ok, I've just learnt what 'statement-expressions' are 
(http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html). Would this be 
the first use of these in lttng-ust? If so, I'm wary of making lttng-ust 
dependent on this gcc extension. Would it be dependent on this? It is up 
to the user to decide what to pass to the macro, but the macro may 
impose constraints by way of how the arguments are employed within the 
macro...


As it happens, we compile with -pedantic which won't allow 
statement-expressions. (As an aside, -pedantic doesn't like tracepoint 
that don't take any arguments because it expects the ... to have at 
least one argument).


My example above (that doesn't use statement-expressions - I removed the 
round brackets) compiles correctly. But it you introduce a comma then 
the compiler seems to interpret this as an argument separator. So this 
works:


  #include stdio.h
  #include stdlib.h

  #define tracepoint_cond(provider, name, cond, pre, post, ...) \
  do { \
  if (caa_unlikely(__tracepoint_##provider##___##name.state)) { \
  if (cond) { \
  pre \
__tracepoint_cb_##provider##___##name(__VA_ARGS__); \
  post \
  } \
  } \
  } \
  while (0)

  int main() {
  int i = 1, j = 1;

  char * a;
  tracepoint_cond(provider, name,
  i == j,  /* condition */
  {   /* pre */
  a = malloc(16);
  memset(a, 0, 16);
  },
  {   /* post */
  free(a);
  int dummy1;
  },
  a
 );
  return 0;
  }

But changing tracepoint_cond to this breaks it:

  tracepoint_cond(provider, name,
  i == j,  /* condition */
  {   /* pre */
  a = malloc(16);
  memset(a, 0, 16);
  },
  {   /* post */
  free(a);
  int dummy1, dummy2;  /* XXX */
  },
  a
 );

Examining the pre-processed code reveals that the comma causes dummy2 to 
become a subsequent argument to the macro and land in the ... region, 
and hell breaks loose.


Do you think we could come up with a scheme that doesn't impose the use 
of statement-expressions, but supports them if they are provided? In my 
example, I simply provide 'i == j' as the condition, but a 
statement-expression would also work. Are we conflating separate ideas - 
the idea of user conditions and the idea of setup/cleanup?



While we are there, it would be good to make the pre handler test a
condition. For your use-case, you would just have to pass a pre :

  { printf(pre\n);  a = malloc(16); 1; }

So we could do:

if (pre)
 __tracepoint_cb_##provider##___##name(__VA_ARGS__);
(post)

and therefore support not only to setup something, but also to add an
extra check on whether tracing should be skipped or not. If someone
passes 1 as end of the compound statement, it will always evaluate to
1, and therefore the compiler will remove any extra branch in -O2.

One question stands though: how would we integrate this with sdt.h
STAP_PROVEV() ?

I'm yet to look at this.

Thanks,
Dave

--
The information contained in this transmission may be confidential. Any 
disclosure, copying, or further distribution of confidential information is not 
permitted unless such privilege is explicitly granted in writing by Quantum. 
Quantum reserves the right to have electronic communications, including email 
and attachments, sent across its networks filtered through anti virus and spam 
software programs and retain such messages in order to 

Re: [lttng-dev] Test if tracepoint is enabled

2012-12-04 Thread David Bryant

On 05/12/12 00:32, Mathieu Desnoyers wrote:

Hrm. So what you would like is something like:

int tracepoint_get_state(provider, name);

So you could use it for your setup and cleanup. However, let's see the
possible use of this construct:

1 - this construct would be OK:

if (tracepoint_get_state(myprovider, myname)) {
 setup();
 tracepoint(myprovider, myname, args...);
 cleanup();
}

but we see that the state test would happen twice, which is somewhat
inefficient.

But the actual problem comes from this construct, which is _not_ OK, and
racy:

2 -

if (tracepoint_get_state(myprovider, myname))
 setup();
tracepoint(myprovider, myname, args...);
if (tracepoint_get_state(myprovider, myname))
 cleanup();

The problem is that users would expect that some synchronization
magically happen when enabling/disabling tracepoints, but it's not the
case. So we could very well end up executing just the cleanup, or just
the tracepoint, or 2 of the 3, if we hit the tracepoint while it is
being enabled/disabled.

Providing this level of deep access into the tracepoint structures seems
error-prone (as shown by construct #2), and inefficient (as shown by the
2 tests performed by construct #1).

This is why I am tempted to introduce a tracepoint_cond() or something
similar, to ensure that no racy construct can be created, and ensure
that we only test the tracepoint state once per site.

Thoughts ?

This construct avoids the inefficiency of checking tracepoint state twice:

if (tracepoint_get_state(myprovider, myname) {
setup();
tracepoint_force(myprovider, myname, args...);
cleanup();
}

ie, tracepoint_force() doesn't re-check the state. However, it relies on 
the user adhering to the pattern. tracepoint_force() could also be 
misused, violating the state of enabled/disabled tracepoints.


I take your point about the user being easily misled. It's not obvious 
enough that tracepoints are enabled/disabled asynchronously and we 
should only provide safe constructs that are compatible with that model.


So, building on your example:

#define tracepoint_cond(provider, name, pre, post, ...) \
do { \
if (caa_unlikely(__tracepoint_##provider##___##name.state)) { \
pre \
__tracepoint_cb_##provider##___##name(__VA_ARGS__); \
post \
} \
} \
while (0)

And a contrived example:

#include stdio.h
#include stdlib.h

int main() {
char * a;
tracepoint_cond(provider, name,
{ printf(pre\n);  a = malloc(16); },
{ printf(post\n); free(a);}
   );
return 0;
}

This is ok. But more work with the macro handling would be required to 
get the pre/post code fragments through as parameters. The example only 
compiles because its pre/post arguments don't contain any commas.


What do you think?

Thanks,
Dave

--
The information contained in this transmission may be confidential. Any 
disclosure, copying, or further distribution of confidential information is not 
permitted unless such privilege is explicitly granted in writing by Quantum. 
Quantum reserves the right to have electronic communications, including email 
and attachments, sent across its networks filtered through anti virus and spam 
software programs and retain such messages in order to comply with applicable 
data security and retention requirements. Quantum is not responsible for the 
proper and complete transmission of the substance of this communication or for 
any delay in its receipt.

___
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev


Re: [lttng-dev] Test if tracepoint is enabled

2012-12-03 Thread Mathieu Desnoyers
* David Bryant (david.bry...@quantum.com) wrote:
 Hi all,

 Is it feasible to have an officially supported way of determining if a  
 tracepoint is currently enabled?

 In my code I would like to test if the tracepoint is enabled, and if it  
 isn't, avoid doing expensive setup work.

 I've been doing the following:

   if  
 (__builtin_expect(!!(__tracepoint_sample_component___message.state), 0)) 
 {
   /* setup work */
   tracepoint(sample_component, message);
   /* cleanup work */
   }

 But it's weak for two reasons:

  * The 'state' attribute goes true when the tracepoint is enabled, but
stays true after the tracepoint is disabled. It only goes false when
the session is destroyed.
  * It uses a private / unofficial API

 What I'd like is an official API that correctly evaluates whether a  
 tracepoint is enabled or not?

 Is this possible?

Something like:

   tracepoint_cond(provider, name, cond, ...)

might do it.

Where cond would be an expression (could be a statement-expression),
e.g.:

tracepoint_cond(myprovider, myevent,
({
a = something;
z = other;
a == z;
}),
a, z);

So we could, in addition to perform some setup, also evaluate a
condition before calling the tracepoint. The macro might look like
(without the '\' at EOL):

#define tracepoint_cond(provider, name, cond, ...)
do {
if (caa_unlikely(__tracepoint_##provider##___##name.state)) {
if (cond)

__tracepoint_cb_##provider##___##name(__VA_ARGS__);
}
} while (0)

So in your case, a statement-expression that evaluates to true would
be fine.

Note that adding support for STAP_PROBEV in there might be a bit less
straightforward, because STAP_PROBEV don't depend on the tracepoint
state.

Thoughts ?

Thanks,

Mathieu



 Thanks,
 Dave

 --
 The information contained in this transmission may be confidential. Any 
 disclosure, copying, or further distribution of confidential information is 
 not permitted unless such privilege is explicitly granted in writing by 
 Quantum. Quantum reserves the right to have electronic communications, 
 including email and attachments, sent across its networks filtered through 
 anti virus and spam software programs and retain such messages in order to 
 comply with applicable data security and retention requirements. Quantum is 
 not responsible for the proper and complete transmission of the substance of 
 this communication or for any delay in its receipt.

 ___
 lttng-dev mailing list
 lttng-dev@lists.lttng.org
 http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev


-- 
Mathieu Desnoyers
Operating System Efficiency RD Consultant
EfficiOS Inc.
http://www.efficios.com

___
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev


Re: [lttng-dev] Test if tracepoint is enabled

2012-12-03 Thread David Bryant

On 04/12/12 01:04, Mathieu Desnoyers wrote:

* David Bryant (david.bry...@quantum.com) wrote:

Hi all,

Is it feasible to have an officially supported way of determining if a
tracepoint is currently enabled?

In my code I would like to test if the tracepoint is enabled, and if it
isn't, avoid doing expensive setup work.

I've been doing the following:

   if
(__builtin_expect(!!(__tracepoint_sample_component___message.state), 0))
{
   /* setup work */
   tracepoint(sample_component, message);
   /* cleanup work */
   }

But it's weak for two reasons:

  * The 'state' attribute goes true when the tracepoint is enabled, but
stays true after the tracepoint is disabled. It only goes false when
the session is destroyed.
  * It uses a private / unofficial API

What I'd like is an official API that correctly evaluates whether a
tracepoint is enabled or not?

Is this possible?

Something like:

tracepoint_cond(provider, name, cond, ...)

might do it.

Where cond would be an expression (could be a statement-expression),
e.g.:

tracepoint_cond(myprovider, myevent,
 ({
 a = something;
 z = other;
 a == z;
 }),
 a, z);

So we could, in addition to perform some setup, also evaluate a
condition before calling the tracepoint. The macro might look like
(without the '\' at EOL):

#define tracepoint_cond(provider, name, cond, ...)
 do {
 if (caa_unlikely(__tracepoint_##provider##___##name.state)) {
 if (cond)
 
__tracepoint_cb_##provider##___##name(__VA_ARGS__);
 }
 } while (0)

Hi Mathieu,

Your proposal seems to introduce a way of providing an additional 
condition for whether to trigger the tracepoint, ie, not only would the 
tracepoint need to be enabled but also 'cond' must be satisfied. This is 
cool, but what I want right now is simply a way of determining whether a 
tracepoint is enabled. If it isn't enabled then I won't do the 
setup/cleanup work to prepare the arguments.


I've been consulting __tracepoint_##provider##___##name.state but am 
unsatisfied because it's unofficial API and it isn't quite the right test.


Thanks,
Dave

So in your case, a statement-expression that evaluates to true would
be fine.

Note that adding support for STAP_PROBEV in there might be a bit less
straightforward, because STAP_PROBEV don't depend on the tracepoint
state.

Thoughts ?

Thanks,

Mathieu



Thanks,
Dave

--
The information contained in this transmission may be confidential. Any 
disclosure, copying, or further distribution of confidential information is not 
permitted unless such privilege is explicitly granted in writing by Quantum. 
Quantum reserves the right to have electronic communications, including email 
and attachments, sent across its networks filtered through anti virus and spam 
software programs and retain such messages in order to comply with applicable 
data security and retention requirements. Quantum is not responsible for the 
proper and complete transmission of the substance of this communication or for 
any delay in its receipt.
___
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev





___
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev