Changeset e74cb73 in mainline for generic/src/ipc/ipc.c


Ignore:
Timestamp:
2006-03-14T09:30:07Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d1f8a87
Parents:
27810c5
Message:

Added skeleton name service.
Cleanup for IPC to use mutexes instead of spinlocks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/ipc/ipc.c

    r27810c5 re74cb73  
    3232 */
    3333
    34 #include <synch/waitq.h>
     34#include <synch/condvar.h>
     35#include <synch/mutex.h>
    3536#include <ipc/ipc.h>
    3637#include <errno.h>
     
    4445#include <proc/thread.h>
    4546
    46 answerbox_t *ipc_central_box;
     47/* Open channel that is assigned automatically to new tasks */
     48answerbox_t *ipc_phone_0 = NULL;
    4749
    4850static slab_cache_t *ipc_call_slab;
     
    6466}
    6567
     68/** Initialize allocated call */
     69void ipc_call_init(call_t *call)
     70{
     71        call->callerbox = &TASK->answerbox;
     72        call->flags = IPC_CALL_STATIC_ALLOC;
     73}
     74
    6675/** Deallocate call stracuture */
    6776void ipc_call_free(call_t *call)
     
    7483void ipc_answerbox_init(answerbox_t *box)
    7584{
    76         spinlock_initialize(&box->lock, "abox_lock");
    77         waitq_initialize(&box->wq);
     85        mutex_initialize(&box->mutex);
     86        condvar_initialize(&box->cv);
    7887        list_initialize(&box->connected_phones);
    7988        list_initialize(&box->calls);
     
    8998       
    9099        phone->callee = box;
    91         spinlock_lock(&box->lock);
     100
     101        mutex_lock(&box->mutex);
    92102        list_append(&phone->list, &box->connected_phones);
    93         spinlock_unlock(&box->lock);
     103        mutex_unlock(&box->mutex);
    94104}
    95105
     
    101111        ASSERT(box);
    102112
    103         spinlock_lock(&box->lock);
     113        mutex_lock(&box->mutex);
    104114        list_remove(&phone->list);
    105         spinlock_unlock(&box->lock);
     115        mutex_unlock(&box->mutex);
    106116}
    107117
     
    131141        ASSERT(box);
    132142
    133         spinlock_lock(&box->lock);
     143        mutex_lock(&box->mutex);
    134144        list_append(&request->list, &box->calls);
    135         spinlock_unlock(&box->lock);
    136         waitq_wakeup(&box->wq, 0);
     145        mutex_unlock(&box->mutex);
     146        condvar_signal(&box->cv);
    137147}
    138148
     
    148158        request->flags |= IPC_CALL_ANSWERED;
    149159
    150         spinlock_lock(&box->lock);
    151         spinlock_lock(&callerbox->lock);
    152 
     160        mutex_lock(&box->mutex);
    153161        list_remove(&request->list);
     162        mutex_unlock(&box->mutex);
     163
     164        mutex_lock(&callerbox->mutex);
    154165        list_append(&request->list, &callerbox->answers);
    155         waitq_wakeup(&callerbox->wq, 0);
    156 
    157         spinlock_unlock(&callerbox->lock);
    158         spinlock_unlock(&box->lock);
     166        mutex_unlock(&callerbox->mutex);
     167        condvar_signal(&callerbox->cv);
    159168}
    160169
     
    168177        call_t *request;
    169178
    170         if ((flags & IPC_WAIT_NONBLOCKING)) {
    171                 if (waitq_sleep_timeout(&box->wq,SYNCH_NO_TIMEOUT,SYNCH_NON_BLOCKING) == ESYNCH_WOULD_BLOCK)
    172                         return 0;
    173         } else {
    174                 waitq_sleep(&box->wq);
     179        mutex_lock(&box->mutex);
     180        while (1) {
     181                if (!list_empty(&box->answers)) {
     182                        /* Handle asynchronous answers */
     183                        request = list_get_instance(box->answers.next, call_t, list);
     184                        list_remove(&request->list);
     185                } else if (!list_empty(&box->calls)) {
     186                        /* Handle requests */
     187                        request = list_get_instance(box->calls.next, call_t, list);
     188                        list_remove(&request->list);
     189                        /* Append request to dispatch queue */
     190                        list_append(&request->list, &box->dispatched_calls);
     191                } else {
     192                        if (!(flags & IPC_WAIT_NONBLOCKING)) {
     193                                condvar_wait(&box->cv, &box->mutex);
     194                                continue;
     195                        }
     196                        if (condvar_trywait(&box->cv, &box->mutex) != ESYNCH_WOULD_BLOCK)
     197                                continue;
     198                        request = NULL;
     199                }
     200                break;
    175201        }
    176 
    177 
    178         // TODO - might need condition variable+mutex if we want to support
    179         // removing of requests from queue before dispatch
    180         spinlock_lock(&box->lock);
    181         /* Handle answers first */
    182         if (!list_empty(&box->answers)) {
    183                 request = list_get_instance(box->answers.next, call_t, list);
    184                 list_remove(&request->list);
    185         } else {
    186                 ASSERT (! list_empty(&box->calls));
    187                 request = list_get_instance(box->calls.next, call_t, list);
    188                 list_remove(&request->list);
    189                 /* Append request to dispatch queue */
    190                 list_append(&request->list, &box->dispatched_calls);
    191         }
    192         spinlock_unlock(&box->lock);
    193 
     202        mutex_unlock(&box->mutex);
    194203        return request;
    195204}
     
    203212                                          NULL, NULL, 0);
    204213}
    205 
    206 static void ipc_phonecompany_thread(void *data)
    207 {
    208         call_t *call;
    209 
    210         printf("Phone company started.\n");
    211         while (1) {
    212                 call = ipc_wait_for_call(&TASK->answerbox, 0);
    213                 printf("Received phone call - %P %P\n",
    214                        call->data[0], call->data[1]);
    215                 call->data[0] = 0xbabaaaee;;
    216                 call->data[1] = 0xaaaaeeee;
    217                 ipc_answer(&TASK->answerbox, call);
    218                 printf("Call answered.\n");
    219         }
    220 }
    221 
    222 void ipc_create_phonecompany(void)
    223 {
    224         thread_t *t;
    225        
    226         if ((t = thread_create(ipc_phonecompany_thread, "phonecompany",
    227                                TASK, 0)))
    228                 thread_ready(t);
    229         else
    230                 panic("thread_create/phonecompany");
    231 
    232         ipc_central_box = &TASK->answerbox;
    233 }
Note: See TracChangeset for help on using the changeset viewer.