]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/cell/spufs/sputrace.c
Merge commit 'origin' into master
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / cell / spufs / sputrace.c
index 2ece399f2862361aaa0789f08a49a4bae169043e..d0b1f3f4d9c887de9a902b4e511c0a2940a4aa02 100644 (file)
@@ -40,6 +40,7 @@ static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
 static ktime_t sputrace_start;
 static unsigned long sputrace_head, sputrace_tail;
 static struct sputrace *sputrace_log;
+static int sputrace_logging;
 
 static int sputrace_used(void)
 {
@@ -79,6 +80,11 @@ static ssize_t sputrace_read(struct file *file, char __user *buf,
                char tbuf[128];
                int width;
 
+               /* If we have data ready to return, don't block waiting
+                * for more */
+               if (cnt > 0 && sputrace_used() == 0)
+                       break;
+
                error = wait_event_interruptible(sputrace_wait,
                                                 sputrace_used() > 0);
                if (error)
@@ -109,24 +115,49 @@ static ssize_t sputrace_read(struct file *file, char __user *buf,
 
 static int sputrace_open(struct inode *inode, struct file *file)
 {
+       int rc;
+
        spin_lock(&sputrace_lock);
+       if (sputrace_logging) {
+               rc = -EBUSY;
+               goto out;
+       }
+
+       sputrace_logging = 1;
        sputrace_head = sputrace_tail = 0;
        sputrace_start = ktime_get();
+       rc = 0;
+
+out:
        spin_unlock(&sputrace_lock);
+       return rc;
+}
 
+static int sputrace_release(struct inode *inode, struct file *file)
+{
+       spin_lock(&sputrace_lock);
+       sputrace_logging = 0;
+       spin_unlock(&sputrace_lock);
        return 0;
 }
 
 static const struct file_operations sputrace_fops = {
-       .owner  = THIS_MODULE,
-       .open   = sputrace_open,
-       .read   = sputrace_read,
+       .owner   = THIS_MODULE,
+       .open    = sputrace_open,
+       .read    = sputrace_read,
+       .release = sputrace_release,
 };
 
 static void sputrace_log_item(const char *name, struct spu_context *ctx,
                struct spu *spu)
 {
        spin_lock(&sputrace_lock);
+
+       if (!sputrace_logging) {
+               spin_unlock(&sputrace_lock);
+               return;
+       }
+
        if (sputrace_avail() > 1) {
                struct sputrace *t = sputrace_log + sputrace_head;