POK(kernelpart)
portqueueingsend.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/sched.h>
24 #include <core/time.h>
25 
26 #include <middleware/port.h>
27 #include <middleware/queue.h>
28 
29 extern pok_port_t pok_ports[POK_CONFIG_NB_PORTS];
30 extern pok_queue_t pok_queue;
31 
32 
33 pok_ret_t pok_port_queueing_send (const pok_port_id_t id,
34  const void* data,
35  const pok_port_size_t len,
36  uint64_t timeout)
37 {
38  pok_lockobj_lockattr_t lockattr;
39  (void) lockattr;
40 
41  pok_ret_t ret;
42 
43  if (id > POK_CONFIG_NB_PORTS)
44  {
45  return POK_ERRNO_EINVAL;
46  }
47 
48  if (len <= 0)
49  {
50  return POK_ERRNO_SIZE;
51  }
52 
53  if (data == NULL)
54  {
55  return POK_ERRNO_EINVAL;
56  }
57 
58  if (! pok_own_port (POK_SCHED_CURRENT_PARTITION, id))
59  {
60  return POK_ERRNO_PORT;
61  }
62 
63  if (pok_ports[id].ready != TRUE)
64  {
65  return POK_ERRNO_PORT;
66  }
67 
68  if (len > pok_ports[id].size)
69  {
70  return POK_ERRNO_SIZE;
71  }
72 
73  if (pok_ports[id].direction != POK_PORT_DIRECTION_OUT)
74  {
75  return POK_ERRNO_DIRECTION;
76  }
77 
78  if (pok_ports[id].partition != POK_SCHED_CURRENT_PARTITION)
79  {
80  return POK_ERRNO_EPERM;
81  }
82 
83  if (pok_ports[id].kind != POK_PORT_KIND_QUEUEING)
84  {
85  return POK_ERRNO_KIND;
86  }
87 
88  ret = pok_lockobj_lock (&pok_ports[id].lock, NULL);
89 
90  if (ret != POK_ERRNO_OK)
91  {
92  return ret;
93  }
94 
95  if (timeout != 0)
96  {
97  timeout = timeout + POK_GETTICK();
98  }
99 
100  while (len > pok_port_available_size (id))
101  {
102  if (timeout == 0)
103  {
104  pok_lockobj_unlock (&pok_ports[id].lock, NULL);
105  return POK_ERRNO_FULL;
106  }
107  else
108  {
109  ret = pok_lockobj_eventwait (&pok_ports[id].lock, timeout);
110  if (ret != POK_ERRNO_OK)
111  {
112  pok_lockobj_unlock (&pok_ports[id].lock, NULL);
113  return (ret);
114  }
115  }
116  }
117 
118  pok_port_write (id, data, len);
119 
120  pok_ports[id].must_be_flushed = TRUE;
121 
122  ret = pok_lockobj_unlock (&pok_ports[id].lock, NULL);
123 
124  if (ret != POK_ERRNO_OK)
125  {
126  return ret;
127  }
128  return POK_ERRNO_OK;
129 }
130 
131 #endif
132