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

Diff of /rtmk/ipc-syscall.c

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

revision 1.9 by jrydberg, Wed Feb 20 20:04:42 2002 UTC revision 1.10 by jrydberg, Thu Feb 21 20:14:42 2002 UTC
# Line 102  rtmk_msg_trap (struct rtmk_msg_header *m Line 102  rtmk_msg_trap (struct rtmk_msg_header *m
102    
103        if (thread->ipc_length < ikm->length)        if (thread->ipc_length < ikm->length)
104          {          {
105            thread->ipc_result = MSG_RCV_TOO_SMALL;            thread->ipc_result = MSG_RECV_TOO_SMALL;
106            thread_unlock (thread);            thread_unlock (thread);
107            SPLON (spl);            SPLON (spl);
108    
# Line 110  rtmk_msg_trap (struct rtmk_msg_header *m Line 110  rtmk_msg_trap (struct rtmk_msg_header *m
110            goto retry_waiting_thread;            goto retry_waiting_thread;
111          }          }
112    
113        thread->ipc_result = MSG_SUCCESS;        thread->ipc_result = KERN_SUCCESS;
114        thread->ipc_kmsg   = ikm;        thread->ipc_kmsg   = ikm;
115        thread_unlock (thread);        thread_unlock (thread);
116        SPLON (spl);        SPLON (spl);
# Line 127  rtmk_msg_trap (struct rtmk_msg_header *m Line 127  rtmk_msg_trap (struct rtmk_msg_header *m
127        /* Enqueue message on port message queue.  Since we do not        /* Enqueue message on port message queue.  Since we do not
128           want to block the kernel (??) we override message queue.  */           want to block the kernel (??) we override message queue.  */
129                
130        result = ipc_mqueue_enqueue (send_port->mqueue, ikm, true);        result = ipc_mqueue_enqueue (&send_port->mqueue, ikm, true);
131        thread_lock_unlock (& send_port->lock);            thread_lock_unlock (& send_port->lock);    
132        assert (result == false);        assert (result == false);
133      }      }
# Line 135  rtmk_msg_trap (struct rtmk_msg_header *m Line 135  rtmk_msg_trap (struct rtmk_msg_header *m
135  }  }
136    
137  /* Message receive continuation point.  */  /* Message receive continuation point.  */
   
138  static void  static void
139  receive_continuation (void)  receive_continuation (void)
140  {  {
# Line 157  receive_continuation (void) Line 156  receive_continuation (void)
156    thread_syscall_return (kr);    thread_syscall_return (kr);
157  }  }
158    
159    /* Timeout function for receving messages.  This function is called
160       when we timeout a receive operation.  ??? lock thread?  */
161    void
162    timeout_receive (void *arg)
163    {
164      struct thread *thread = (struct thread *) arg;
165      struct ipc_port *port;
166    
167      trace_printf ("timeout receive");
168    
169      port = thread->ipc_blocked_port;
170      thread->ipc_blocked_port = 0;
171    
172      if (port)
173        {
174          thread_lock_write (& port->lock);
175          ipc_tqueue_remove (&port->waiting_threads, thread);
176          thread_lock_unlock (& port->lock);
177        }
178    
179      thread->ipc_result = MSG_RECV_TIMEOUT;
180      thread_interrupt (thread);
181    }
182    
183    /* Timeout function for sending messages.  This function is called
184       when we timeout a blocked thread waiting to send a message to a port.  */
185    void
186    timeout_send (void *arg)
187    {
188      struct thread *thread = (struct thread *) arg;
189      struct ipc_port *port;
190    
191      trace_printf ("timeout send");
192    
193      port = thread->ipc_blocked_port;
194      thread->ipc_blocked_port = 0;
195    
196      if (port)
197        {
198          thread_lock_write (& port->lock);
199          ipc_tqueue_remove (&port->blocked_threads, thread);
200          thread_lock_unlock (& port->lock);
201        }
202    
203      thread->ipc_result = MSG_SEND_TIMEOUT;
204      thread_interrupt (thread);
205    }
206    
207    
208  /* User entry point for IPC send/receive.  /* User entry point for IPC send/receive.
209    
# Line 172  static kern_return_t Line 219  static kern_return_t
219  internal_msg_trap (struct rtmk_msg_header *msgh, rtmk_msg_option_t options,  internal_msg_trap (struct rtmk_msg_header *msgh, rtmk_msg_option_t options,
220                     rtmk_msg_size_t send_size, rtmk_port_t send_name,                     rtmk_msg_size_t send_size, rtmk_port_t send_name,
221                     rtmk_msg_size_t recv_size, rtmk_port_t recv_name,                     rtmk_msg_size_t recv_size, rtmk_port_t recv_name,
222                     rtmk_msg_timeout_t timeout)                     rtmk_msg_timeout_t timeout_value)
223  {  {
224    struct thread *thread = THREAD_CURRENT (), *target;    struct thread *thread = THREAD_CURRENT (), *target;
225    struct ipc_object *object = THREAD_CURRENT()->task->ipc_object;    struct ipc_object *object = THREAD_CURRENT()->task->ipc_object;
# Line 192  internal_msg_trap (struct rtmk_msg_heade Line 239  internal_msg_trap (struct rtmk_msg_heade
239    
240    if (options & RTMK_MSG_OPTION_RECEIVE)    if (options & RTMK_MSG_OPTION_RECEIVE)
241      {      {
242        ipc_object_lock (object);        if (recv_name == RTMK_PORT_NULL || recv_name == RTMK_PORT_DEAD)
243            return MSG_RECV_INVALID_SRC;
244    
245          ipc_object_lock (object);
246            
247        kr = ipc_object_lookup (object, recv_name, &entry);        kr = ipc_object_lookup (object, recv_name, &entry);
248        if (kr != KERN_SUCCESS)        if (kr != KERN_SUCCESS)
249          {          {
# Line 216  internal_msg_trap (struct rtmk_msg_heade Line 266  internal_msg_trap (struct rtmk_msg_heade
266    
267    if (options & RTMK_MSG_OPTION_SEND)    if (options & RTMK_MSG_OPTION_SEND)
268      {      {
269          if (send_name == RTMK_PORT_NULL || send_name == RTMK_PORT_DEAD)
270            return MSG_SEND_INVALID_DST;
271    
272        if (send_size < sizeof (struct rtmk_msg_header))        if (send_size < sizeof (struct rtmk_msg_header))
273          return MSG_SEND_TOO_SMALL;          return MSG_SEND_TOO_SMALL;
274    
# Line 234  internal_msg_trap (struct rtmk_msg_heade Line 287  internal_msg_trap (struct rtmk_msg_heade
287            return KERN_INVALID_RIGHT;            return KERN_INVALID_RIGHT;
288          }          }
289    
   
290        /* Obtain read lock to port.  */        /* Obtain read lock to port.  */
291        port = entry->ie_port;            port = entry->ie_port;    
292        thread_lock_read (&port->lock);        thread_lock_read (&port->lock);
# Line 294  internal_msg_trap (struct rtmk_msg_heade Line 346  internal_msg_trap (struct rtmk_msg_heade
346    
347                if (LIKELY (options & RTMK_MSG_OPTION_RECEIVE))                if (LIKELY (options & RTMK_MSG_OPTION_RECEIVE))
348                  {                  {
349                    if (UNLIKELY (receive_port != reply_kmsg->remote_port))                    if (UNLIKELY (receive_port != reply_kmsg->destination_port))
350                      {                      {
351                        trace_printf ("rp %p kmsg rp %p %p esp %x",                        trace_printf ("rp %p kmsg rp %p %p esp %x",
352                                      receive_port, reply_kmsg->remote_port,                                      receive_port, reply_kmsg->destination_port,
353                                      reply_kmsg->local_port, get_esp ());                                      reply_kmsg->reply_port, get_esp ());
354                        trace_printf ("kmsg length %d",                        trace_printf ("kmsg length %d",
355                                      reply_kmsg->header.msgh_length);                                      reply_kmsg->header.msgh_length);
356                        goto enqueue_kernel_reply;                        goto enqueue_kernel_reply;
# Line 373  internal_msg_trap (struct rtmk_msg_heade Line 425  internal_msg_trap (struct rtmk_msg_heade
425               next thread (reporting error to thread).  */               next thread (reporting error to thread).  */
426            if (target->ipc_length < kmsg->length)            if (target->ipc_length < kmsg->length)
427              {              {
428                target->ipc_result = MSG_RCV_TOO_SMALL;                target->ipc_result = MSG_RECV_TOO_SMALL;
429    
430                thread_unlock (target);                thread_unlock (target);
431                SPLON (spl);                SPLON (spl);
# Line 386  internal_msg_trap (struct rtmk_msg_heade Line 438  internal_msg_trap (struct rtmk_msg_heade
438                            
439            /* TARGET is the thread that we can pass message to.  */            /* TARGET is the thread that we can pass message to.  */
440    
441              /* We have to cancel any pending callout.  */
442              untimeout (timeout_receive, target);
443    
444            target->ipc_result = KERN_SUCCESS;            target->ipc_result = KERN_SUCCESS;
445            target->ipc_kmsg = kmsg;            target->ipc_kmsg = kmsg;
446            target->ipc_blocked_port = 0;            target->ipc_blocked_port = 0;
# Line 409  internal_msg_trap (struct rtmk_msg_heade Line 464  internal_msg_trap (struct rtmk_msg_heade
464            assert (failed == false);            assert (failed == false);
465    
466          enqueue_message_on_port:          enqueue_message_on_port:
467              result = ipc_mqueue_enqueue (&port->mqueue, kmsg, false);
           result = ipc_mqueue_enqueue (port->mqueue, kmsg, false);  
468            if (result == true            if (result == true
469                && (options & RTMK_MSG_OPTION_NOBLOCK) == 0)                && (options & RTMK_MSG_OPTION_NOBLOCK) == 0)
470              {              {
471                /* The port has reached its queue limit.  What we have                /* The port has reached its queue limit.  What we have
472                   to do now is to put the thread to sleep until there's                   to do now is to put the thread to sleep until there's
473                   space available on the queue.  */                   space available on the queue.  */
   
474                assert (0);                assert (0);
475              }              }
476            else if (result == true)            else if (result == true)
# Line 440  internal_msg_trap (struct rtmk_msg_heade Line 493  internal_msg_trap (struct rtmk_msg_heade
493    if (options & RTMK_MSG_OPTION_RECEIVE)    if (options & RTMK_MSG_OPTION_RECEIVE)
494      {      {
495        if (recv_size < sizeof (struct rtmk_msg_header))        if (recv_size < sizeof (struct rtmk_msg_header))
496          return MSG_RCV_TOO_SMALL;          return MSG_RECV_TOO_SMALL;
497    
498        /* We get a read lock until we have to change anything in the port.  */        /* We get a read lock until we have to change anything in the port.  */
499        port = receive_port;        port = receive_port;
# Line 451  internal_msg_trap (struct rtmk_msg_heade Line 504  internal_msg_trap (struct rtmk_msg_heade
504        /* If we have message on queue we dequeue it and check size against        /* If we have message on queue we dequeue it and check size against
505           receive buffer.  ??? dequeue first when size checked?  */           receive buffer.  ??? dequeue first when size checked?  */
506    
507        if (ipc_mqueue_empty (port->mqueue) == false)        if (ipc_mqueue_empty (&port->mqueue) == false)
508          {          {
509            kmsg = ipc_mqueue_first (port->mqueue);            kmsg = ipc_mqueue_first (&port->mqueue);
510    
511            if (recv_size < kmsg->header.msgh_length)            if (recv_size < kmsg->header.msgh_length)
512              {              {
513                thread_lock_unlock (&port->lock);                thread_lock_unlock (&port->lock);
514                ipc_object_unlock (object);                ipc_object_unlock (object);
515                return MSG_RCV_TOO_SMALL;                return MSG_RECV_TOO_SMALL;
516              }              }
517    
518            /* Upgrade to write lock for port.  */            /* Upgrade to write lock for port.  */
# Line 468  internal_msg_trap (struct rtmk_msg_heade Line 521  internal_msg_trap (struct rtmk_msg_heade
521    
522            /* Remove message from port message queue and copy message into            /* Remove message from port message queue and copy message into
523               task address/ipc space.  Discard message if we fail.  */               task address/ipc space.  Discard message if we fail.  */
524            kmsg = ipc_mqueue_dequeue (port->mqueue);            kmsg = ipc_mqueue_dequeue (& port->mqueue);
525    
526            kr = ipc_kmsg_copyout (thread->task, msgh, kmsg);            kr = ipc_kmsg_copyout (thread->task, msgh, kmsg);
527            if (kr != KERN_SUCCESS)            if (kr != KERN_SUCCESS)
# Line 503  internal_msg_trap (struct rtmk_msg_heade Line 556  internal_msg_trap (struct rtmk_msg_heade
556            /* Store pointer to user message buffer in threads scratch area.            /* Store pointer to user message buffer in threads scratch area.
557               Set maximum length of message.  Unlock port when done.  */               Set maximum length of message.  Unlock port when done.  */
558    
559              /* ??? lock thread here?  */
560            thread->scratch_area [0] = msgh;            thread->scratch_area [0] = msgh;
561            thread->ipc_length = recv_size;            thread->ipc_length = recv_size;
562            thread->ipc_blocked_port = port;            thread->ipc_blocked_port = port;
563            thread_lock_unlock (&port->lock);            thread_lock_unlock (&port->lock);
564    
565              if (options & RTMK_MSG_OPTION_TIMEOUT)
566                timeout (timeout_value, timeout_receive, thread);
567    
568            thread_wait ((int) port, &object->lock, receive_continuation);            thread_wait ((int) port, &object->lock, receive_continuation);
569          }          }
570      }      }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

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