]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ferret/lib/consumer/__llist_consumer.c
update
[l4.git] / l4 / pkg / ferret / lib / consumer / __llist_consumer.c
1 /**
2  * \file   ferret/lib/sensor/__llist_consumer.c
3  * \brief  locked list consumer functions.
4  *
5  * \date   2007-05-16
6  * \author Martin Pohlack  <mp26@os.inf.tu-dresden.de>
7  */
8 /*
9  * (c) 2007-2009 Technische Universität Dresden
10  * This file is part of TUD:OS and distributed under the terms of the
11  * GNU General Public License 2.
12  * Please see the COPYING-GPL-2 file for details.
13  */
14 #if FERRET_LLIST_MAGIC != ahK6eeNa
15 #error Do not directly include this file, use a propper wrapper!
16 #endif
17 #undef FERRET_LLIST_MAGIC
18
19 #include <stdlib.h>
20
21 // fixme: debug
22 //#include <l4/log/l4log.h>
23
24 #include <l4/ferret/types.h>
25
26 #include <l4/sys/ipc.h>
27
28 // fixme: maybe later we need functions to get more than 1 element out
29 //        of the buffer, thereby saving some locking overhead
30 int PREFIX(get)(PREFIX(moni_t) * list, ferret_list_entry_t * el)
31 {
32     uint32_t index;
33
34     /* 1. lock list
35      * 2. check if new data is available (no -> return -1)
36      * 3. check if we lost something and update lost counter
37      * 4. compute offset in locked list's data array
38      * 5. copy data
39      * 6. lock list
40      */
41
42     FERRET_LLIST_LOCAL_LOCK(list);
43
44     // check if we have new events for the consumer
45     if (L4_UNLIKELY(list->glob->head.value <= list->next_read.value))
46         return -1;  // we have no new events
47     // check if we have lost events
48     if (L4_UNLIKELY(list->glob->head.value - list->next_read.value >
49                     list->glob->count))
50     {
51         list->lost += list->glob->head.value - list->next_read.value -
52                       list->glob->count;
53         list->next_read.value = list->glob->head.value - list->glob->count;
54     }
55     index = list->next_read.lh.low & list->glob->count_mask;
56     memcpy(el, list->out_buf + (index << list->glob->element_size_ld),
57            list->glob->element_size);
58
59     list->next_read.value++;
60     FERRET_LLIST_LOCAL_UNLOCK(list);
61     return 0;
62
63     //return -2;  // corrupt sensor
64 }
65
66 void PREFIX(init_consumer)(void ** addr)
67 {
68     PREFIX(moni_t) * temp;
69
70     temp = malloc(sizeof(PREFIX(moni_t)));
71
72     // setup some pointers
73     temp->glob    = *addr;  // store pointer to global structure
74     temp->out_buf = temp->glob->data;
75
76     // copy header
77     temp->header.major    = temp->glob->header.major;
78     temp->header.minor    = temp->glob->header.minor;
79     temp->header.instance = temp->glob->header.instance;
80     temp->header.type     = temp->glob->header.type;
81
82     // init. local information
83     temp->lost            = 0;
84     temp->next_read.value = 0;
85
86 #ifdef FERRET_LLIST_HAVE_LOCAL_LOCK
87     FERRET_LLIST_LOCAL_INIT(temp);
88 #endif
89
90     *addr = temp;
91 }
92
93 void PREFIX(free_consumer)(void ** addr)
94 {
95     void * temp = ((PREFIX(moni_t) *)(*addr))->glob;
96
97     free(*addr);
98
99     *addr = temp;
100 }