]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/arm-ds5-gator.git/blob - driver/gator_annotate.c
e096d1552e3140d5c0401e6a6d2e1e40b66149bb
[android-sdk/arm-ds5-gator.git] / driver / gator_annotate.c
1 /**
2  * Copyright (C) ARM Limited 2010-2011. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  */
10 #include <linux/slab.h>
11 #include <linux/fs.h>
12 #include <linux/mm.h>
13 #include <linux/sched.h>
14 #include <asm/uaccess.h>
15 #include <asm/current.h>
16 #include <linux/spinlock.h>
18 #define ANNOTATE_SIZE   (16*1024)
19 static DEFINE_SPINLOCK(annotate_lock);
20 static char *annotateBuf;
21 static char *annotateBuf0;
22 static char *annotateBuf1;
23 static int annotatePos;
24 static int annotateSel;
25 static bool collect_annotations = false;
27 static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
28 {
29         char tempBuffer[512];
30         int retval, remaining, size;
32         if (*offset)
33                 return -EINVAL;
35         // determine size to capture
36         remaining = ANNOTATE_SIZE - annotatePos - 256; // pad for headers and release
37         size = count < sizeof(tempBuffer) ? count : sizeof(tempBuffer);
38         size = size < remaining ? size : remaining;
39         if (size <= 0) {
40                 wake_up(&gator_buffer_wait);
41                 return 0;
42         }
44         // copy from user space
45         retval = copy_from_user(tempBuffer, buf, size);
46         if (retval == 0) {
47                 // synchronize shared variables annotateBuf and annotatePos
48                 spin_lock(&annotate_lock);
49                 if (collect_annotations && annotateBuf) {
50                         uint32_t tid = current->pid;
51                         uint64_t time = gator_get_time();
52                         uint32_t cpuid = smp_processor_id();
53                         int pos = annotatePos;
54                         pos += gator_write_packed_int(&annotateBuf[pos], tid);
55                         pos += gator_write_packed_int64(&annotateBuf[pos], time);
56                         pos += gator_write_packed_int(&annotateBuf[pos], cpuid);
57                         pos += gator_write_packed_int(&annotateBuf[pos], size);
58                         memcpy(&annotateBuf[pos], tempBuffer, size);
59                         annotatePos = pos + size;
60                 }
61                 spin_unlock(&annotate_lock);
63                 // return the number of bytes written
64                 retval = size;
65         } else {
66                 retval = -EINVAL;
67         }
69         return retval;
70 }
72 static int annotate_release(struct inode *inode, struct file *file)
73 {
74         int remaining = ANNOTATE_SIZE - annotatePos;
75         if (remaining < 16) {
76                 return -EFAULT;
77         }
79         spin_lock(&annotate_lock);
80         if (annotateBuf) {
81                 uint32_t tid = current->pid;
82                 int pos = annotatePos;
83                 pos += gator_write_packed_int(&annotateBuf[pos], tid);
84                 pos += gator_write_packed_int64(&annotateBuf[pos], 0); // time
85                 pos += gator_write_packed_int(&annotateBuf[pos], 0); // cpuid
86                 pos += gator_write_packed_int(&annotateBuf[pos], 0); // size
87                 annotatePos = pos;
88         }
89         spin_unlock(&annotate_lock);
91         return 0;
92 }
94 static const struct file_operations annotate_fops = {
95         .write          = annotate_write,
96         .release        = annotate_release
97 };
99 static int gator_annotate_create_files(struct super_block *sb, struct dentry *root)
101         annotateBuf = NULL;
102         return gatorfs_create_file_perm(sb, root, "annotate", &annotate_fops, 0666);
105 static int gator_annotate_init(void)
107         annotateBuf0 = kmalloc(ANNOTATE_SIZE, GFP_KERNEL);
108         annotateBuf1 = kmalloc(ANNOTATE_SIZE, GFP_KERNEL);
109         if (!annotateBuf0 || !annotateBuf1)
110                 return -1;
111         return 0;
114 static int gator_annotate_start(void)
116         annotateSel = 0;
117         annotatePos = 1;
118         annotateBuf = annotateBuf0;
119         annotateBuf[0] = FRAME_ANNOTATE;
120         collect_annotations = true;
121         return 0;
124 static void gator_annotate_stop(void)
126         collect_annotations = false;
129 static void gator_annotate_shutdown(void)
131         spin_lock(&annotate_lock);
132         annotateBuf = NULL;
133         spin_unlock(&annotate_lock);
136 static void gator_annotate_exit(void)
138         spin_lock(&annotate_lock);
139         kfree(annotateBuf0);
140         kfree(annotateBuf1);
141         annotateBuf = annotateBuf0 = annotateBuf1 = NULL;
142         spin_unlock(&annotate_lock);
145 static int gator_annotate_ready(void)
147         return annotatePos > 1 && annotateBuf;
150 static int gator_annotate_read(char **buffer)
152         int len;
154         if (!gator_annotate_ready())
155                 return 0;
157         annotateSel = !annotateSel;
159         if (buffer)
160                 *buffer = annotateBuf;
162         spin_lock(&annotate_lock);
163         len = annotatePos;
164         annotateBuf = annotateSel ? annotateBuf1 : annotateBuf0;
165         annotateBuf[0] = FRAME_ANNOTATE;
166         annotatePos = 1;
167         spin_unlock(&annotate_lock);
169         return len;