45 #include "contiki-net.h"
52 #ifdef QUEUEBUF_CONF_REF_NUM
53 #define QUEUEBUF_REF_NUM QUEUEBUF_CONF_REF_NUM
55 #define QUEUEBUF_REF_NUM 2
62 struct queuebuf *next;
68 enum {IN_RAM, IN_CFS} location;
71 struct queuebuf_data *ram_ptr;
79 struct queuebuf_data {
82 struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS];
83 struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS];
93 MEMB(bufmem,
struct queuebuf, QUEUEBUF_NUM);
94 MEMB(refbufmem,
struct queuebuf_ref, QUEUEBUF_REF_NUM);
95 MEMB(buframmem,
struct queuebuf_data, QUEUEBUFRAM_NUM);
103 #define NQBUF_FILES 4
104 #define NQBUF_PER_FILE 256
105 #define QBUF_FILE_SIZE (NQBUF_PER_FILE*sizeof(struct queuebuf_data))
106 #define NQBUF_ID (NQBUF_PER_FILE * NQBUF_FILES)
115 static struct queuebuf_data tmpdata;
117 static struct queuebuf *tmpdata_qbuf =
NULL;
119 static int next_swap_id = 0;
121 static struct qbuf_file qbuf_files[NQBUF_FILES];
123 static struct ctimer renew_timer;
135 #define PRINTF(...) printf(__VA_ARGS__)
140 #ifdef QUEUEBUF_CONF_STATS
141 #define QUEUEBUF_STATS QUEUEBUF_CONF_STATS
143 #define QUEUEBUF_STATS 0
147 uint8_t queuebuf_len, queuebuf_ref_len, queuebuf_max_len;
153 qbuf_renew_file(
int file)
157 name[0] =
'a' + file;
159 if(qbuf_files[file].renewable == 1) {
160 PRINTF(
"qbuf_renew_file: removing file %d\n", file);
165 PRINTF(
"qbuf_renew_file: cfs open error\n");
167 qbuf_files[file].fd = ret;
168 qbuf_files[file].usage = 0;
169 qbuf_files[file].renewable = 0;
174 qbuf_renew_all(
void *unused)
177 for(i=0; i<NQBUF_FILES; i++) {
178 if(qbuf_files[i].renewable == 1) {
186 queuebuf_remove_from_file(
int swap_id)
190 fileid = swap_id / NQBUF_PER_FILE;
191 qbuf_files[fileid].usage--;
194 if(qbuf_files[fileid].usage == 0 && fileid != next_swap_id / NQBUF_PER_FILE) {
195 qbuf_files[fileid].renewable = 1;
200 if(tmpdata_qbuf->swap_id == swap_id) {
201 tmpdata_qbuf->swap_id = -1;
207 get_new_swap_id(
void)
210 int swap_id = next_swap_id;
211 fileid = swap_id / NQBUF_PER_FILE;
212 if(swap_id % NQBUF_PER_FILE == 0) {
213 if(qbuf_files[fileid].renewable) {
214 qbuf_renew_file(fileid);
216 if(qbuf_files[fileid].usage>0) {
220 qbuf_files[fileid].usage++;
221 next_swap_id = (next_swap_id+1) % NQBUF_ID;
227 queuebuf_flush_tmpdata(
void)
232 queuebuf_remove_from_file(tmpdata_qbuf->swap_id);
233 tmpdata_qbuf->swap_id = get_new_swap_id();
234 if(tmpdata_qbuf->swap_id == -1) {
237 fileid = tmpdata_qbuf->swap_id / NQBUF_PER_FILE;
238 offset = (tmpdata_qbuf->swap_id % NQBUF_PER_FILE) *
sizeof(
struct queuebuf_data);
239 fd = qbuf_files[fileid].fd;
242 PRINTF(
"queuebuf_flush_tmpdata: cfs seek error\n");
245 ret = cfs_write(fd, &tmpdata,
sizeof(
struct queuebuf_data));
247 PRINTF(
"queuebuf_flush_tmpdata: cfs write error\n");
255 static struct queuebuf_data *
256 queuebuf_load_to_ram(
struct queuebuf *b)
260 if(b->location == IN_RAM) {
263 if(tmpdata_qbuf && tmpdata_qbuf->swap_id == b->swap_id) {
268 fileid = b->swap_id / NQBUF_PER_FILE;
269 offset = (b->swap_id % NQBUF_PER_FILE) *
sizeof(
struct queuebuf_data);
270 fd = qbuf_files[fileid].fd;
273 PRINTF(
"queuebuf_load_to_ram: cfs seek error\n");
275 ret = cfs_read(fd, &tmpdata,
sizeof(
struct queuebuf_data));
277 PRINTF(
"queuebuf_load_to_ram: cfs read error\n");
285 static struct queuebuf_data *
286 queuebuf_load_to_ram(
struct queuebuf *b)
297 for(i=0; i<NQBUF_FILES; i++) {
298 qbuf_files[i].renewable = 1;
306 queuebuf_max_len = QUEUEBUF_NUM;
312 queuebuf_new_from_packetbuf_debug(
const char *file,
int line)
315 queuebuf_new_from_packetbuf(
void)
318 struct queuebuf *buf;
319 struct queuebuf_ref *rbuf;
331 PRINTF(
"queuebuf_new_from_packetbuf: could not allocate a reference queuebuf\n");
333 return (
struct queuebuf *)rbuf;
335 struct queuebuf_data *buframptr;
347 if(buf->ram_ptr !=
NULL) {
348 buf->location = IN_RAM;
349 buframptr = buf->ram_ptr;
351 buf->location = IN_CFS;
354 buframptr = &tmpdata;
357 if(buf->ram_ptr ==
NULL) {
358 PRINTF(
"queuebuf_new_from_packetbuf: could not queuebuf data\n");
361 buframptr = buf->ram_ptr;
365 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
368 if(buf->location == IN_CFS) {
369 if(queuebuf_flush_tmpdata() == -1) {
379 PRINTF(
"queuebuf len %d\n", queuebuf_len);
380 printf(
"#A q=%d\n", queuebuf_len);
381 if(queuebuf_len == queuebuf_max_len + 1) {
389 PRINTF(
"queuebuf_new_from_packetbuf: could not allocate a queuebuf\n");
396 queuebuf_update_attr_from_packetbuf(
struct queuebuf *buf)
398 struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf);
399 packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
401 if(buf->location == IN_CFS) {
402 queuebuf_flush_tmpdata();
408 queuebuf_free(
struct queuebuf *buf)
410 if(memb_inmemb(&bufmem, buf)) {
412 if(buf->location == IN_RAM) {
415 queuebuf_remove_from_file(buf->swap_id);
423 printf(
"#A q=%d\n", queuebuf_len);
428 }
else if(memb_inmemb(&refbufmem, buf)) {
437 queuebuf_to_packetbuf(
struct queuebuf *b)
439 struct queuebuf_ref *r;
440 if(memb_inmemb(&bufmem, b)) {
441 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
443 packetbuf_attr_copyfrom(buframptr->attrs, buframptr->addrs);
444 }
else if(memb_inmemb(&refbufmem, b)) {
445 r = (
struct queuebuf_ref *)b;
454 queuebuf_dataptr(
struct queuebuf *b)
456 struct queuebuf_ref *r;
458 if(memb_inmemb(&bufmem, b)) {
459 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
460 return buframptr->data;
461 }
else if(memb_inmemb(&refbufmem, b)) {
462 r = (
struct queuebuf_ref *)b;
469 queuebuf_datalen(
struct queuebuf *b)
471 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
472 return buframptr->len;
476 queuebuf_addr(
struct queuebuf *b, uint8_t type)
478 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
479 return &buframptr->addrs[type - PACKETBUF_ADDR_FIRST].addr;
483 queuebuf_attr(
struct queuebuf *b, uint8_t type)
485 struct queuebuf_data *buframptr = queuebuf_load_to_ram(b);
486 return buframptr->attrs[type].val;
490 queuebuf_debug_print(
void)
494 printf(
"queuebuf_list: ");
497 printf(
"%s,%d,%lu ", q->file, q->line, q->time);