Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


add v3vee copyright info
[palacios.git] / linux_module / util-ringbuffer.c
1 /*\r
2  * This file is part of the Palacios Virtual Machine Monitor developed\r
3  * by the V3VEE Project with funding from the United States National\r
4  * Science Foundation and the Department of Energy.\r
5  *\r
6  * The V3VEE Project is a joint project between Northwestern University\r
7  * and the University of New Mexico.  You can find out more at\r
8  * http://www.v3vee.org\r
9  *\r
10  * Copyright (c) 2010, Lei Xia <lxia@northwestern.edu>\r
11  * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org>\r
12  * All rights reserved.\r
13  *\r
14  * This is free software.  You are permitted to use, redistribute,\r
15  * and modify it under the terms of the GNU General Public License\r
16  * Version 2 (GPLv2).  The accompanying COPYING file contains the\r
17  * full text of the license.\r
18  */\r
19 \r
20 #include <linux/errno.h>\r
21 #include <linux/percpu.h>\r
22 #include <linux/sched.h>\r
23 \r
24 #include "palacios.h"\r
25 #include "util-ringbuffer.h"\r
26 \r
27 void init_ringbuf(struct ringbuf * ring, unsigned int size) {\r
28     ring->buf = kmalloc(size, GFP_KERNEL);\r
29     ring->size = size;\r
30   \r
31     ring->start = 0;\r
32     ring->end = 0;\r
33     ring->current_len = 0;\r
34 }\r
35 \r
36 struct ringbuf * create_ringbuf(unsigned int size) {\r
37     struct ringbuf * ring = (struct ringbuf *)kmalloc(sizeof(struct ringbuf), GFP_KERNEL);\r
38     init_ringbuf(ring, size);\r
39 \r
40     return ring;\r
41 }\r
42 \r
43 void free_ringbuf(struct ringbuf * ring) {\r
44     kfree(ring->buf);\r
45     kfree(ring);\r
46 }\r
47 \r
48 static inline unsigned char * get_read_ptr(struct ringbuf * ring) {\r
49     return (unsigned char *)(ring->buf + ring->start);\r
50 }\r
51 \r
52 \r
53 static inline unsigned char * get_write_ptr(struct ringbuf * ring) {\r
54     return (unsigned char *)(ring->buf + ring->end);\r
55 }\r
56 \r
57 static inline int get_read_section_size(struct ringbuf * ring) {\r
58     return ring->size - ring->start;\r
59 }\r
60 \r
61 \r
62 static inline int get_write_section_size(struct ringbuf * ring) {\r
63     return ring->size - ring->end;\r
64 }\r
65 \r
66 \r
67 static inline int is_read_loop(struct ringbuf * ring, unsigned int len) {\r
68     if ((ring->start >= ring->end) && (ring->current_len > 0)) {\r
69         // end is past the end of the buffer\r
70         if (get_read_section_size(ring) < len) {\r
71             return 1;\r
72         }\r
73     }\r
74     return 0;\r
75 }\r
76 \r
77 \r
78 static inline int is_write_loop(struct ringbuf * ring, unsigned int len) {\r
79     if ((ring->end >= ring->start) && (ring->current_len < ring->size)) {\r
80         // end is past the end of the buffer\r
81         if (get_write_section_size(ring) < len) {\r
82             return 1;\r
83         }\r
84     }\r
85     return 0;\r
86 }\r
87 \r
88 \r
89 static inline int ringbuf_avail_space(struct ringbuf * ring) {\r
90     return ring->size - ring->current_len;\r
91 }\r
92 \r
93 \r
94 int ringbuf_data_len(struct ringbuf * ring) {\r
95     return ring->current_len;\r
96 }\r
97 \r
98 \r
99 static inline int ringbuf_capacity(struct ringbuf * ring) {\r
100     return ring->size;\r
101 }\r
102 \r
103 \r
104 int ringbuf_read(struct ringbuf * ring, unsigned char * dst, unsigned int len) {\r
105     int read_len = 0;\r
106     int ring_data_len = ring->current_len;\r
107 \r
108     read_len = (len > ring_data_len) ? ring_data_len : len;\r
109 \r
110     if (is_read_loop(ring, read_len)) {\r
111         int section_len = get_read_section_size(ring);\r
112 \r
113         memcpy(dst, get_read_ptr(ring), section_len);\r
114         memcpy(dst + section_len, ring->buf, read_len - section_len);\r
115     \r
116         ring->start = read_len - section_len;\r
117     } else {\r
118         memcpy(dst, get_read_ptr(ring), read_len);\r
119     \r
120         ring->start += read_len;\r
121     }\r
122 \r
123     ring->current_len -= read_len;\r
124 \r
125     return read_len;\r
126 }\r
127 \r
128 \r
129 #if 0\r
130 \r
131 static int ringbuf_peek(struct ringbuf * ring, unsigned char * dst, unsigned int len) {\r
132     int read_len = 0;\r
133     int ring_data_len = ring->current_len;\r
134 \r
135     read_len = (len > ring_data_len) ? ring_data_len : len;\r
136 \r
137     if (is_read_loop(ring, read_len)) {\r
138         int section_len = get_read_section_size(ring);\r
139 \r
140         memcpy(dst, get_read_ptr(ring), section_len);\r
141         memcpy(dst + section_len, ring->buf, read_len - section_len);\r
142     } else {\r
143         memcpy(dst, get_read_ptr(ring), read_len);\r
144     }\r
145 \r
146     return read_len;\r
147 }\r
148 \r
149 \r
150 static int ringbuf_delete(struct ringbuf * ring, unsigned int len) {\r
151     int del_len = 0;\r
152     int ring_data_len = ring->current_len;\r
153 \r
154     del_len = (len > ring_data_len) ? ring_data_len : len;\r
155 \r
156     if (is_read_loop(ring, del_len)) {\r
157         int section_len = get_read_section_size(ring);\r
158         ring->start = del_len - section_len;\r
159     } else {\r
160         ring->start += del_len;\r
161     }\r
162 \r
163     ring->current_len -= del_len;\r
164     return del_len;\r
165 }\r
166 #endif\r
167 \r
168 int ringbuf_write(struct ringbuf * ring, unsigned char * src, unsigned int len) {\r
169     int write_len = 0;\r
170     int ring_avail_space = ring->size - ring->current_len;\r
171   \r
172     write_len = (len > ring_avail_space) ? ring_avail_space : len;\r
173 \r
174     if (is_write_loop(ring, write_len)) {\r
175         int section_len = get_write_section_size(ring);\r
176     \r
177         memcpy(get_write_ptr(ring), src, section_len);\r
178         ring->end = 0;\r
179 \r
180         memcpy(get_write_ptr(ring), src + section_len, write_len - section_len);\r
181 \r
182         ring->end += write_len - section_len;\r
183     } else {\r
184         memcpy(get_write_ptr(ring), src, write_len);\r
185 \r
186         ring->end += write_len;\r
187     }\r
188 \r
189     ring->current_len += write_len;\r
190 \r
191     return write_len;\r
192 }\r
193 \r