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.


added copyright tags
[palacios.git] / palacios / src / geekos / ring_buffer.c
1 /* Northwestern University */
2 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
3
4 #include <geekos/ring_buffer.h>
5 #include <geekos/malloc.h>
6 #include <geekos/ktypes.h>
7 #include <geekos/debug.h>
8
9
10 void init_ring_buffer(struct ring_buffer * ring, uint_t size) {
11   ring->buf = Malloc(size);
12   ring->size = size;
13   
14   ring->start = 0;
15   ring->end = 0;
16   ring->current_len = 0;
17 }
18
19
20 struct ring_buffer * create_ring_buffer(uint_t size) {
21   struct ring_buffer * ring = (struct ring_buffer *)Malloc(sizeof(struct ring_buffer));
22
23   init_ring_buffer(ring, size);
24
25   return ring;
26 }
27
28 void free_ring_buffer(struct ring_buffer * ring) {
29   Free(ring->buf);
30   Free(ring);
31 }
32
33
34
35
36
37 static inline uchar_t * get_read_ptr(struct ring_buffer * ring) {
38   return (uchar_t *)(ring->buf + ring->start);
39 }
40
41 static inline uchar_t * get_write_ptr(struct ring_buffer * ring) {
42   return (uchar_t *)(ring->buf + ring->end);
43 }
44
45
46 static inline int get_read_section_size(struct ring_buffer * ring) {
47   return ring->size - ring->start;
48 }
49
50 static inline int get_write_section_size(struct ring_buffer * ring) {
51   return ring->size - ring->end;
52 }
53
54 static inline int is_read_loop(struct ring_buffer * ring, uint_t len) {
55   if ((ring->start >= ring->end) && (ring->current_len > 0)) {
56     // end is past the end of the buffer
57     if (get_read_section_size(ring) < len) {
58       return 1;
59     }
60   }
61   return 0;
62 }
63
64
65 static inline int is_write_loop(struct ring_buffer * ring, uint_t len) {
66   if ((ring->end >= ring->start) && (ring->current_len < ring->size)) {
67     // end is past the end of the buffer
68     if (get_write_section_size(ring) < len) {
69       return 1;
70     }
71   }
72   return 0;
73 }
74
75
76 int rb_data_len(struct ring_buffer * ring) {
77   return ring->current_len;
78 }
79
80 int rb_capacity(struct ring_buffer * ring) {
81   return ring->size;
82 }
83
84 int rb_read(struct ring_buffer * ring, char * dst, uint_t len) {
85   int read_len = 0;
86   int ring_data_len = ring->current_len;
87
88   read_len = (len > ring_data_len) ? ring_data_len : len;
89
90   if (is_read_loop(ring, read_len)) {
91     int section_len = get_read_section_size(ring);
92
93     memcpy(dst, get_read_ptr(ring), section_len);
94     memcpy(dst + section_len, ring->buf, read_len - section_len);
95     
96     ring->start = read_len - section_len;
97   } else {
98     memcpy(dst, get_read_ptr(ring), read_len);
99     
100     ring->start += read_len;
101   }
102
103   ring->current_len -= read_len;
104
105   return read_len;
106 }
107
108
109
110
111 int rb_peek(struct ring_buffer * ring, char * dst, uint_t len) {
112   int read_len = 0;
113   int ring_data_len = ring->current_len;
114
115   read_len = (len > ring_data_len) ? ring_data_len : len;
116
117   if (is_read_loop(ring, read_len)) {
118     int section_len = get_read_section_size(ring);
119
120     memcpy(dst, get_read_ptr(ring), section_len);
121     memcpy(dst + section_len, ring->buf, read_len - section_len);
122   } else {
123     memcpy(dst, get_read_ptr(ring), read_len);
124   }
125
126   return read_len;
127 }
128
129
130 int rb_delete(struct ring_buffer * ring, uint_t len) {
131   int del_len = 0;
132   int ring_data_len = ring->current_len;
133
134   del_len = (len > ring_data_len) ? ring_data_len : len;
135
136   if (is_read_loop(ring, del_len)) {
137     int section_len = get_read_section_size(ring);
138     ring->start = del_len - section_len;
139   } else {
140     ring->start += del_len;
141   }
142
143   ring->current_len -= del_len;
144   return del_len;
145 }
146
147
148 int rb_write(struct ring_buffer * ring, char * src, uint_t len) {
149   int write_len = 0;
150   int ring_avail_space = ring->size - ring->current_len;
151   
152   write_len = (len > ring_avail_space) ? ring_avail_space : len;
153
154
155   if (is_write_loop(ring, write_len)) {
156     int section_len = get_write_section_size(ring);
157     
158     memcpy(get_write_ptr(ring), src, section_len);
159     ring->end = 0;
160
161     memcpy(get_write_ptr(ring), src + section_len, write_len - section_len);
162
163     ring->end += write_len - section_len;
164   } else {
165     memcpy(get_write_ptr(ring), src, write_len);
166
167     ring->end += write_len;
168   }
169
170   ring->current_len += write_len;
171
172   return write_len;
173 }
174
175
176 void print_ring_buffer(struct ring_buffer * ring) {
177   int ctr = 0;
178   
179   for (ctr = 0; ctr < ring->current_len; ctr++) {
180     int index = (ctr + ring->start) % ring->size;
181
182     PrintBoth("Entry %d (index=%d): %c\n", ctr, index, ring->buf[index]);
183   }
184 }