aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2008-05-22 00:44:33 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2008-05-22 00:43:00 -0400
commitf7fa194248788d8ed57739caa6d7bd363f9b9596 (patch)
tree808d3aa8cb7ebd8ca0defee39b0943d20c0749ce
parent3e3261bbf150f586df310be84c606c4910aa6501 (diff)
Feather-Trace: support draining of trace buffer
-rw-r--r--litmus/trace.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/litmus/trace.c b/litmus/trace.c
index 489e23e8a6..67e40d623b 100644
--- a/litmus/trace.c
+++ b/litmus/trace.c
@@ -88,6 +88,9 @@ static void free_ft_buffer(struct ft_buffer* buf)
88static DECLARE_MUTEX(feather_lock); 88static DECLARE_MUTEX(feather_lock);
89static int use_count = 0; 89static int use_count = 0;
90 90
91/* used for draining the FT buffers */
92static int enabled_events = 0;
93
91static int trace_release(struct inode *in, struct file *filp) 94static int trace_release(struct inode *in, struct file *filp)
92{ 95{
93 int err = -EINVAL; 96 int err = -EINVAL;
@@ -104,6 +107,7 @@ static int trace_release(struct inode *in, struct file *filp)
104 if (use_count == 1) { 107 if (use_count == 1) {
105 /* disable events */ 108 /* disable events */
106 ft_disable_all_events(); 109 ft_disable_all_events();
110 enabled_events = 0;
107 111
108 /* wait for any pending events to complete */ 112 /* wait for any pending events to complete */
109 set_current_state(TASK_UNINTERRUPTIBLE); 113 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -125,7 +129,6 @@ out:
125 return err; 129 return err;
126} 130}
127 131
128
129static ssize_t trace_read(struct file *filp, char __user *to, size_t len, 132static ssize_t trace_read(struct file *filp, char __user *to, size_t len,
130 loff_t *f_pos) 133 loff_t *f_pos)
131{ 134{
@@ -141,6 +144,7 @@ static ssize_t trace_read(struct file *filp, char __user *to, size_t len,
141 144
142 while (len >= sizeof(struct timestamp)) { 145 while (len >= sizeof(struct timestamp)) {
143 if (ft_buffer_read(trace_ts_buf, &ts)) { 146 if (ft_buffer_read(trace_ts_buf, &ts)) {
147 /* FIXME: avoid double copy */
144 if (copy_to_user(to, &ts, sizeof(struct timestamp))) { 148 if (copy_to_user(to, &ts, sizeof(struct timestamp))) {
145 error = -EFAULT; 149 error = -EFAULT;
146 break; 150 break;
@@ -149,14 +153,17 @@ static ssize_t trace_read(struct file *filp, char __user *to, size_t len,
149 to += sizeof(struct timestamp); 153 to += sizeof(struct timestamp);
150 error += sizeof(struct timestamp); 154 error += sizeof(struct timestamp);
151 } 155 }
152 } else { 156 } else if (enabled_events) {
157 /* only wait if there are any events enabled */
153 set_current_state(TASK_INTERRUPTIBLE); 158 set_current_state(TASK_INTERRUPTIBLE);
154 schedule_timeout(50); 159 schedule_timeout(50);
155 if (signal_pending(current)) { 160 if (signal_pending(current)) {
156 error = -ERESTARTSYS; 161 error = -ERESTARTSYS;
157 break; 162 break;
158 } 163 }
159 } 164 } else
165 /* nothing left to get, return to user space */
166 break;
160 } 167 }
161 up(&feather_lock); 168 up(&feather_lock);
162out: 169out:
@@ -203,10 +210,12 @@ static ssize_t trace_write(struct file *filp, const char __user *from,
203 printk(KERN_INFO 210 printk(KERN_INFO
204 "Disabling feather-trace event %lu.\n", id); 211 "Disabling feather-trace event %lu.\n", id);
205 ft_disable_event(id); 212 ft_disable_event(id);
213 enabled_events--;
206 } else { 214 } else {
207 printk(KERN_INFO 215 printk(KERN_INFO
208 "Enabling feather-trace event %lu.\n", id); 216 "Enabling feather-trace event %lu.\n", id);
209 ft_enable_event(id); 217 ft_enable_event(id);
218 enabled_events++;
210 } 219 }
211 error += sizeof(long); 220 error += sizeof(long);
212 } 221 }