/[rtmk]/rtmk/ipc-kmsg.c
ViewVC logotype

Diff of /rtmk/ipc-kmsg.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by jrydberg, Fri Dec 7 22:08:23 2001 UTC revision 1.2 by jrydberg, Mon Dec 10 20:51:04 2001 UTC
# Line 15  You should have received a copy of the G Line 15  You should have received a copy of the G
15  along with this program; if not, write to the Free Software  along with this program; if not, write to the Free Software
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17    
18    #include <rtmk/vm-types.h>
19    #include <rtmk/vm-param.h>
20    #include <rtmk/ipc-types.h>
21    #include <rtmk/ipc-port.h>
22    #include <rtmk/ipc-return.h>
23    #include <stdarg.h>
24    
25  #include "tm.h"  #include "tm.h"
26  #include "trace.h"  #include "trace.h"
27    #include "vm-slab.h"
28    #include "vm-kmem.h"
29    #include "task.h"
30    
31  #include "ipc-kmsg.h"  #include "ipc-kmsg.h"
32    
33    #define KERNEL_MSG_SIZE (256-4)
34    
35    static struct kmem_cache *atomic_cache;
36    static struct kmem_cache *kmsg_cache;
37    
38    /* Copy a message into a kernel buffer must be done in a "atomic"
39       manner.  If we fail somewhere along the road the task state must
40       be unchanged.
41    
42       To do this we have hold a list of atomic elements that will be
43       executed when we have checked all rights and permissions.  */
44    
45    enum ipc_atomic_type
46    {
47      IPC_ATOMIC_PORT_REMOVE,       /* Remove port from task.  */
48      IPC_ATOMIC_PORT_REF           /* ??? */
49    };
50    
51    struct ipc_atomic
52    {
53      enum ipc_atomic_type type;
54    
55      union {
56        rtmk_port_t name;
57        struct ipc_port *port;
58      } params;
59    };
60    
61    /* Add a new element to array of atomic operations.  */
62    
63    static void atomic_add (struct ipc_atomic ***atomics, int *n_atomics,
64                            int *n_max_atomics, enum ipc_atomic_type type, ...);
65    
66    /* Execute atomic operations specified in ATOMICS.  */
67    
68    static void atomic_execute (struct task *task, struct ipc_atomic **atomics,
69                                int n_atomics);
70    
71    
72    /* Initialize kernel messages.  */
73    
74    void
75    ipc_kmsg_init (void)
76    {
77      kmsg_cache = kmem_cache_create ("ipc kmsg cache", KERNEL_MSG_SIZE, 0);
78      atomic_cache = kmem_cache_create ("ipc atomic cache",
79                                        sizeof (struct ipc_atomic), 0);
80      assert (kmsg_cache && atomic_cache);
81    }
82    
83    /* Allocate a new kernel message with SIZE bytes payload.  
84       SIZE includes the size of the header.  */
85    
86    struct ipc_kmsg *
87    ipc_kmsg_alloc (vm_size_t size)
88    {
89      struct ipc_kmsg *kmsg;
90    
91      /* Check if we can use memory from the "common size" cache.  */
92    
93      if ((size - sizeof (struct rtmk_msg_header))
94          <= (KERNEL_MSG_SIZE - sizeof (struct ipc_kmsg)))
95        {
96          kmsg = (struct ipc_kmsg *) kmem_cache_alloc (kmsg_cache);
97        }
98    
99      /* We have to allocate more than usual memory for message.  */
100      else
101        {
102          vm_size_t total_size;
103    
104          /* ??? should we not use kmem_malloc?  */
105    
106          total_size = vm_round_page (size + sizeof (struct ipc_kmsg)
107                                      - sizeof (struct rtmk_msg_header));
108          kmsg = (struct ipc_kmsg *) kmem_alloc_wired (VM_MAP_KERNEL (),
109                                                       total_size);
110        }
111    
112      if (kmsg)
113        kmsg->length = size;
114      return kmsg;
115    }
116    
117    /* Free a kernel message allocated with ipc_kmsg_alloc.  */
118    
119  void  void
120  ipc_kmsg_free (struct ipc_kmsg *kmsg)  ipc_kmsg_free (struct ipc_kmsg *kmsg)
121  {  {
122      if ((kmsg->length - sizeof (struct rtmk_msg_header))
123          <= (KERNEL_MSG_SIZE - sizeof (struct ipc_kmsg)))
124        {
125          kmem_cache_free (kmsg_cache, kmsg);
126        }
127      else
128        kmem_free (VM_MAP_KERNEL (), (vm_offset_t) kmsg);
129    }
130    
131    
132    /* Copy in a kernel message from kernel address/ipc space into a
133       kernel message buffer.  TASK must be kernel task.
134    
135       There's one destinction from user and kernel messages; the kernel
136       have rights to all ports so it do not operate on rights (or capabilites),
137       instead it uses points to the IPC port structure.
138    
139       ??? currently OOL memory can not be sent from kernel.  */
140    
141    kern_return_t
142    ipc_kmsg_copyin_kernel (struct task *task, struct ipc_kmsg *kmsg)
143    {
144      struct rtmk_msg_header *msgh = &kmsg->header;
145    
146      /* First we fill the kmsg structure with some information.  */
147    
148      kmsg->remote_port = (struct ipc_port *) msgh->msgh_remote_port;
149      kmsg->local_port  = (struct ipc_port *) msgh->msgh_local_port;
150    
151      /* Kernel never sends simple messages and it never sends to itself.  */
152    
153      kmsg->complex_p   = true;
154      kmsg->intratask_p = false;
155    
156      /* Length field of kmsg is already set by the alloc function.  */
157    
158      /* ??? since we do not support OOL memory from kernel yet,
159            we can just return here since we are done.  */
160      return KERN_SUCCESS;
161    }
162    
163    
164    /* ??? convenience function for expanding an atomic element array.  */
165    
166    static inline void expand_atomic_array (struct ipc_atomic ***atomics,
167                                            int *n_atomics, int *n_max_atomics)
168    {
169      if (*atomics == 0)
170        {
171          *n_max_atomics = 16;
172          *n_atomics = 0;
173          *atomics =
174            (struct ipc_atomic **) kmem_zalloc (*n_max_atomics
175                                                * sizeof (struct ipc_atomic *));
176        }
177    
178      if (*n_atomics == *n_max_atomics)
179        {
180          struct ipc_atomic **new_atomics;
181    
182          *n_max_atomics <<= 1;
183    
184          new_atomics =
185            (struct ipc_atomic **) kmem_zalloc (*n_max_atomics
186                                                * sizeof (struct ipc_atomic *));
187          memcpy (*atomics, new_atomics,
188                  *n_atomics * sizeof (struct ipc_atomic *));
189    
190          kmem_mfree (*atomics);
191          *atomics = new_atomics;
192        }
193    }
194    
195    
196    /* Add an atomic element to list of elements (ATOMIC).  */
197    
198    static void
199    atomic_add (struct ipc_atomic ***atomics, int *n_atomics,
200                int *n_max_atomics, enum ipc_atomic_type type, ...)
201    {
202      struct ipc_atomic *atomic;
203      va_list ap;
204    
205      expand_atomic_array (atomics, n_atomics, n_max_atomics);
206    
207      va_start (ap, type);
208    
209      atomic = kmem_cache_alloc (atomic_cache);
210      atomic->type = type;
211    
212      switch (type)
213        {
214        case IPC_ATOMIC_PORT_REMOVE:
215          {
216            rtmk_port_t name = va_arg (ap, rtmk_port_t);
217            atomic->params.name = name;
218            break;
219          }
220    
221        case IPC_ATOMIC_PORT_REF:
222          {
223            break;
224          }
225        }
226    
227      *atomics[*n_atomics++] = atomic;
228      va_end (ap);
229  }  }
230    
231    /* Execute an array of atomic elements.  This also releases all
232       memory allocated by "atomic_add".  */
233    
234    static void
235    atomic_execute (struct task *task, struct ipc_atomic **atomics,
236                    int n_atomics)
237    {
238      struct ipc_atomic *atomic;
239    
240      int i;
241    
242      for (i = 0; i < n_atomics; i++)
243        {
244          atomic = atomics [i];
245    
246          switch (atomic->type)
247            {
248            case IPC_ATOMIC_PORT_REMOVE:
249              break;
250            case IPC_ATOMIC_PORT_REF:
251              break;
252            }
253          kmem_cache_free (atomic_cache, atomic);
254        }
255      kmem_mfree (atomics);
256    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26