oprofile: adding cpu_buffer_entries()
[linux-2.6-block.git] / drivers / oprofile / cpu_buffer.h
index d3cc26264db55b60948a71b9f8500a236666a64d..6055b5678394bc51fa0ddab7235c15df92682b01 100644 (file)
@@ -52,6 +52,62 @@ DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
 
 void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf);
 
+static inline
+struct op_sample *cpu_buffer_write_entry(struct oprofile_cpu_buffer *cpu_buf)
+{
+       return &cpu_buf->buffer[cpu_buf->head_pos];
+}
+
+static inline
+void cpu_buffer_write_commit(struct oprofile_cpu_buffer *b)
+{
+       unsigned long new_head = b->head_pos + 1;
+
+       /*
+        * Ensure anything written to the slot before we increment is
+        * visible
+        */
+       wmb();
+
+       if (new_head < b->buffer_size)
+               b->head_pos = new_head;
+       else
+               b->head_pos = 0;
+}
+
+static inline
+struct op_sample *cpu_buffer_read_entry(struct oprofile_cpu_buffer *cpu_buf)
+{
+       return &cpu_buf->buffer[cpu_buf->tail_pos];
+}
+
+/* "acquire" as many cpu buffer slots as we can */
+static inline
+unsigned long cpu_buffer_entries(struct oprofile_cpu_buffer *b)
+{
+       unsigned long head = b->head_pos;
+       unsigned long tail = b->tail_pos;
+
+       /*
+        * Subtle. This resets the persistent last_task
+        * and in_kernel values used for switching notes.
+        * BUT, there is a small window between reading
+        * head_pos, and this call, that means samples
+        * can appear at the new head position, but not
+        * be prefixed with the notes for switching
+        * kernel mode or a task switch. This small hole
+        * can lead to mis-attribution or samples where
+        * we don't know if it's in the kernel or not,
+        * at the start of an event buffer.
+        */
+       cpu_buffer_reset(b);
+
+       if (head >= tail)
+               return head - tail;
+
+       return head + (b->buffer_size - tail);
+}
+
 /* transient events for the CPU buffer -> event buffer */
 #define CPU_IS_KERNEL 1
 #define CPU_TRACE_BEGIN 2