--- /dev/null
+
+#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_DEFAULT (~_MARK_PREEMPT | _MARK_TRAP | _MARK_RESCHED)
+
+#define MARK (format, ...) MARK_OPTIONS(MARK_DEFAULT, format, __VA_ARGS__)
+
+ex. i386
+#define MARK_OPTIONS(opt, format, ...) \
+{ \
+ if (opt & _MARK_NO_TRAP) \
+ GEN_MARK(opt, format, __VA_ARGS__); \
+ else \
+ MARK(opt, format, __VA_ARGS__); \
+}
+
+ex. powerpc
+#define MARK_OPTIONS(opt, format, ...) MARK(opt, format, __VA_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();
+}
+
+
+