/[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.6 by jrydberg, Thu Jan 3 01:46:01 2002 UTC revision 1.7 by jrydberg, Sat Jan 5 00:08:30 2002 UTC
# Line 32  Foundation, Inc., 59 Temple Place - Suit Line 32  Foundation, Inc., 59 Temple Place - Suit
32    
33  #define KERNEL_MSG_SIZE (256-4)  #define KERNEL_MSG_SIZE (256-4)
34    
 static struct kmem_cache *atomic_cache;  
35  static struct kmem_cache *kmsg_cache;  static struct kmem_cache *kmsg_cache;
36    
 /* Copy a message into a kernel buffer must be done in a "atomic"  
    manner.  If we fail somewhere along the road the task state must  
    be unchanged.  
   
    To do this we have hold a list of atomic elements that will be  
    executed when we have checked all rights and permissions.  */  
   
 enum ipc_atomic_type  
 {  
   IPC_ATOMIC_PORT_REMOVE,       /* Remove port from task.  */  
   IPC_ATOMIC_PORT_REF           /* ??? */  
 };  
   
 struct ipc_atomic  
 {  
   enum ipc_atomic_type type;  
   
   union {  
     rtmk_port_t name;  
     struct ipc_port *port;  
   } params;  
 };  
   
 /* Add a new element to array of atomic operations.  */  
   
 static void atomic_add (struct ipc_atomic ***atomics, int *n_atomics,  
                         int *n_max_atomics, enum ipc_atomic_type type, ...);  
   
 /* Execute atomic operations specified in ATOMICS.  */  
   
 static void atomic_execute (struct task *task, struct ipc_atomic **atomics,  
                             int n_atomics);  
   
   
37  /* Initialize kernel messages.  */  /* Initialize kernel messages.  */
38    
39  void  void
40  ipc_kmsg_init (void)  ipc_kmsg_init (void)
41  {  {
42    kmsg_cache = kmem_cache_create ("ipc kmsg cache", KERNEL_MSG_SIZE, 0);    kmsg_cache = kmem_cache_create ("ipc kmsg cache", KERNEL_MSG_SIZE, 0);
43    atomic_cache = kmem_cache_create ("ipc atomic cache",    assert (kmsg_cache);
                                     sizeof (struct ipc_atomic), 0);  
   assert (kmsg_cache && atomic_cache);  
44  }  }
45    
46  /* Allocate a new kernel message with SIZE bytes payload.    /* Allocate a new kernel message with SIZE bytes payload.  
# Line 467  ipc_kmsg_copyin (struct task *task, stru Line 430  ipc_kmsg_copyin (struct task *task, stru
430    return KERN_SUCCESS;    return KERN_SUCCESS;
431  }  }
432    
   
 /* ??? convenience function for expanding an atomic element array.  */  
   
 static inline void expand_atomic_array (struct ipc_atomic ***atomics,  
                                         int *n_atomics, int *n_max_atomics)  
 {  
   if (*atomics == 0)  
     {  
       *n_max_atomics = 16;  
       *n_atomics = 0;  
       *atomics =  
         (struct ipc_atomic **) kmem_zalloc (*n_max_atomics  
                                             * sizeof (struct ipc_atomic *));  
     }  
   
   if (*n_atomics == *n_max_atomics)  
     {  
       struct ipc_atomic **new_atomics;  
   
       *n_max_atomics <<= 1;  
   
       new_atomics =  
         (struct ipc_atomic **) kmem_zalloc (*n_max_atomics  
                                             * sizeof (struct ipc_atomic *));  
       memcpy (*atomics, new_atomics,  
               *n_atomics * sizeof (struct ipc_atomic *));  
   
       kmem_mfree (*atomics);  
       *atomics = new_atomics;  
     }  
 }  
   
   
 /* Add an atomic element to list of elements (ATOMIC).  */  
   
 static void  
 atomic_add (struct ipc_atomic ***atomics, int *n_atomics,  
             int *n_max_atomics, enum ipc_atomic_type type, ...)  
 {  
   struct ipc_atomic *atomic;  
   va_list ap;  
   
   expand_atomic_array (atomics, n_atomics, n_max_atomics);  
   
   va_start (ap, type);  
   
   atomic = kmem_cache_alloc (atomic_cache);  
   atomic->type = type;  
   
   switch (type)  
     {  
     case IPC_ATOMIC_PORT_REMOVE:  
       {  
         rtmk_port_t name = va_arg (ap, rtmk_port_t);  
         atomic->params.name = name;  
         break;  
       }  
   
     case IPC_ATOMIC_PORT_REF:  
       {  
         break;  
       }  
     }  
   
   *atomics[*n_atomics++] = atomic;  
   va_end (ap);  
 }  
   
 /* Execute an array of atomic elements.  This also releases all  
    memory allocated by "atomic_add".  */  
   
 static void  
 atomic_execute (struct task *task, struct ipc_atomic **atomics,  
                 int n_atomics)  
 {  
   struct ipc_atomic *atomic;  
   
   int i;  
   
   for (i = 0; i < n_atomics; i++)  
     {  
       atomic = atomics [i];  
   
       switch (atomic->type)  
         {  
         case IPC_ATOMIC_PORT_REMOVE:  
           break;  
         case IPC_ATOMIC_PORT_REF:  
           break;  
         }  
       kmem_cache_free (atomic_cache, atomic);  
     }  
   kmem_mfree (atomics);  
 }  

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

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