POK(kernelpart)
portqueueingreceive.c
Go to the documentation of this file.
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Thu Jan 15 23:34:13 2009
15  */
16 
17 #ifdef POK_NEEDS_PORTS_QUEUEING
18 
19 #include <types.h>
20 #include <errno.h>
21 
22 #include <core/lockobj.h>
23 #include <core/time.h>
24 #include <core/sched.h>
25 
26 #include <middleware/port.h>
27 #include <middleware/queue.h>
28 
29 #include <libc.h>
30 
31 extern pok_port_t pok_ports[POK_CONFIG_NB_PORTS];
32 
33 pok_ret_t pok_port_queueing_receive (const pok_port_id_t id,
34  uint64_t timeout,
35  const pok_port_size_t maxlen,
36  void* data,
37  pok_port_size_t* len)
38 {
39 
40  pok_port_size_t clen;
41  pok_port_size_t rlen;
42  pok_port_size_t toclean;
43  pok_ret_t ret;
44 
45  pok_lockobj_lockattr_t lockattr;
46  (void) lockattr;
47 
48  *len = 0;
49  if (maxlen <= 0)
50  {
51  return POK_ERRNO_EINVAL;
52  }
53 
54  if (id > POK_CONFIG_NB_PORTS)
55  {
56  return POK_ERRNO_EINVAL;
57  }
58 
59  if (! pok_own_port (POK_SCHED_CURRENT_PARTITION, id))
60  {
61  return POK_ERRNO_PORT;
62  }
63 
64  if (pok_ports[id].ready != TRUE)
65  {
66 
67  return POK_ERRNO_PORT;
68  }
69 
70  if (pok_ports[id].kind != POK_PORT_KIND_QUEUEING)
71  {
72  return POK_ERRNO_KIND;
73  }
74 
75  if (pok_ports[id].direction != POK_PORT_DIRECTION_IN)
76  {
77  return POK_ERRNO_DIRECTION;
78  }
79 
80  toclean = maxlen;
81  if (toclean > pok_ports[id].size)
82  {
83  toclean = pok_ports[id].size;
84  }
85 
86  /* Make sure we clean the data buffer before */
87  memset (data, '\0', toclean);
88 
89  /*
90  * TODO : check that the partition has the right
91  * to receive anything
92  */
93 
94  if (timeout > 0)
95  {
96  timeout = timeout + POK_GETTICK();
97  }
98 
99  ret = pok_lockobj_lock (&pok_ports[id].lock, NULL);
100 
101  if (ret != POK_ERRNO_OK)
102  {
103  return ret;
104  }
105  while (pok_ports[id].empty == TRUE)
106  {
107  if (timeout == 0)
108  {
109  pok_lockobj_unlock (&pok_ports[id].lock, NULL);
110  return POK_ERRNO_EMPTY;
111  }
112  else
113  {
114  ret = pok_lockobj_eventwait (&pok_ports[id].lock, timeout);
115  if (ret != POK_ERRNO_OK)
116  {
117  pok_lockobj_unlock (&pok_ports[id].lock, NULL);
118  return ret;
119  }
120  }
121  }
122 
123  clen = pok_port_consumed_size (id);
124 
125  if (maxlen > clen )
126  {
127  rlen = clen;
128  }
129  else
130  {
131  rlen = maxlen;
132  }
133 
134 
135  if (pok_port_get (id, data, rlen) == POK_ERRNO_OK)
136  {
137  *len = rlen;
138  }
139  else
140  {
141  *len = 0;
142  }
143 
144  pok_lockobj_unlock (&pok_ports[id].lock, NULL);
145 
146  return POK_ERRNO_OK;
147 }
148 
149 #endif