
#define MARK_TRAP 1
#define _MARK_TRAP (1 << MARK_TRAP)
  Can generate a trap

#define MARK_PREEMPT 2
#define _MARK_PREEMPT (1 << MARK_PREEMPT)
  Permits blocking calls within probe.
  How to deal with probe removal :
  Each site has its per cpu probe_exec counters. The sum of the signed values
  gives the number of executors. Operations inc/dec on those values are done
  within preempt disable so they can be done non atomically without risking
  to be corrupted by another CPU.
  1 - disable site and remove call
  2 - while sum of probe_exec counters != 0, sleep 50ms
      fail after 10 loops
        - if someone sleeps in here for a long time or waits for 
	  a busy ressource, removal may fail with -EBUSY.

site :

if (enable) {
	preempt_disable();
	probe_exec[smp_processor_id()]++;
	preempt_enable();
	handler();
	preempt_disable();
	probe_exec[smp_processor_id()]--;
	preempt_enable();
}

#define MARK_RESCHED 3
#define _MARK_RESCHED (1 << MARK_RESCHED)
  preempt_schedule() will be called by the marker.

#define MARK_PRINTK 4
#define _MARK_PRINTK (1 << MARK_PRINTK)
  vprintk can be called in the probe/printk can be called as probe.

#define MARK_LOCK_SAFE
#define _MARK_LOCK_SAFE (1 << MARK_LOCK_SAFE)
  It is completely safe to take a lock, disable irqs, softirqs, ... from this marker.
  If unset, checking the context must be done to insure no deadlock or recursive
  call will occur.

#define _MARK_DEFAULT (_MARK_TRAP | _MARK_RESCHED | _MARK_PRINTK)

#define MARK (format, args...) _MARK(MARK_DEFAULT, format, ## args)

ex. i386
#define _MARK(opt, format, args...) \
do { \
	if (opt & _MARK_TRAP) \
		MARK(opt, format, ## args); \
	else \
		GEN_MARK(opt, format, ## args); \
} while (0)

ex. powerpc
#define _MARK(opt, format, args...) MARK(opt, format, ## args);


MARK(opt, format, ...) \
static declare opt in struct; \
if (enable) {
	preempt_disable();
	if (opt & _MARK_PREEMPT) {
		probe_exec[smp_processor_id()]++;
		if (opt & _MARK_RESCHED)
			preempt_enable();
		else
			preempt_enable_no_resched();
	}
	handler();
	if (opt & _MARK_PREEMPT) {
		preempt_disable();
		probe_exec[smp_processor_id()]--;
	}
	if (opt & _MARK_RESCHED)
		preempt_enable();
	else
		preempt_enable_no_resched();
}



