/[hurd]/hurd-l4/libhurd-cap-server/bucket-manage-mt.c
ViewVC logotype

Diff of /hurd-l4/libhurd-cap-server/bucket-manage-mt.c

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

revision 1.10 by marcus, Mon Nov 1 16:39:24 2004 UTC revision 1.11 by neal, Tue Nov 30 10:34:18 2004 UTC
# Line 30  Line 30 
30  #include <pthread.h>  #include <pthread.h>
31    
32  #include <l4.h>  #include <l4.h>
33    #include <compiler.h>
34    
35  #include "cap-server-intern.h"  #include "cap-server-intern.h"
36    
# Line 118  lookup_client (hurd_cap_bucket_t bucket, Line 119  lookup_client (hurd_cap_bucket_t bucket,
119  }  }
120    
121    
122  /* Process the message MSG from thread FROM in worker thread WORKER of  /* Process the message CTX->MSG from thread CTX->FROM in worker thread
123     bucket BUCKET.  Return ECAP_NOREPLY if no reply should be sent.  Any     CTX->WORKER of bucket CTX->BUCKET.  Return ECAP_NOREPLY if no reply
124     other error will be replied to the user.  If 0 is returned, MSG     should be sent.  Any other error will be replied to the user.  If 0
125     must contain the reply message.  */     is returned, CTX->MSG must contain the reply message.  */
126  static error_t  static error_t
127  __attribute__((always_inline))  __attribute__((always_inline))
128  manage_demuxer (hurd_cap_rpc_context_t ctx, _hurd_cap_list_item_t worker)  manage_demuxer (hurd_cap_rpc_context_t ctx, _hurd_cap_list_item_t worker)
# Line 364  manage_mt_worker (void *arg, bool async) Line 365  manage_mt_worker (void *arg, bool async)
365    worker->next = NULL;    worker->next = NULL;
366    worker->prevp = NULL;    worker->prevp = NULL;
367    
368    if (__builtin_expect (async, 0))    if (EXPECT_FALSE (async))
369      {      {
370        /* We have to add ourselves to the free list and inform the        /* We have to add ourselves to the free list and inform the
371           worker_alloc_async thread.  */           worker_alloc_async thread.  */
# Line 401  manage_mt_worker (void *arg, bool async) Line 402  manage_mt_worker (void *arg, bool async)
402    
403    while (1)    while (1)
404      {      {
405        if (__builtin_expect (l4_ipc_failed (msg_tag), 0))        if (EXPECT_FALSE (l4_ipc_failed (msg_tag)))
406          {          {
407            /* Slow path.  */            /* Slow path.  */
408    
# Line 457  manage_mt_worker (void *arg, bool async) Line 458  manage_mt_worker (void *arg, bool async)
458            assert (l4_thread_is_equal (l4_actual_sender (), manager));            assert (l4_thread_is_equal (l4_actual_sender (), manager));
459    
460            pthread_mutex_lock (&bucket->lock);            pthread_mutex_lock (&bucket->lock);
461            /* We process cancellation messages irregardless of the            /* We process cancellation messages regardless of the
462               bucket state.  */               bucket state.  */
463            if (l4_msg_label (ctx.msg) == HURD_CAP_MSG_LABEL_CANCEL)            if (EXPECT_FALSE (l4_msg_label (ctx.msg)
464                                == HURD_CAP_MSG_LABEL_CANCEL))
465              {              {
466                if (l4_untyped_words (l4_msg_msg_tag (ctx.msg)) == 1)                if (l4_untyped_words (l4_msg_msg_tag (ctx.msg)) == 1)
467                  {                  {
# Line 494  manage_mt_worker (void *arg, bool async) Line 496  manage_mt_worker (void *arg, bool async)
496            else            else
497              {              {
498                /* Normal RPCs.  */                /* Normal RPCs.  */
499                if (bucket->state == _HURD_CAP_STATE_BLACK)                if (EXPECT_FALSE (bucket->state == _HURD_CAP_STATE_BLACK))
500                  {                  {
501                    /* The bucket operations have been ended, and the                    /* The bucket operations have been ended, and the
502                       manager has already been canceled.  We know that                       manager has already been canceled.  We know that
# Line 510  manage_mt_worker (void *arg, bool async) Line 512  manage_mt_worker (void *arg, bool async)
512                  }                  }
513                else                else
514                  {                  {
515                    if (bucket->state != _HURD_CAP_STATE_GREEN)                    if (EXPECT_FALSE (bucket->state != _HURD_CAP_STATE_GREEN))
516                      {                      {
517                        /* If we are inhibited, we will have to wait                        /* If we are inhibited, we will have to wait
518                           until we are uninhibited.  */                           until we are uninhibited.  */
# Line 519  manage_mt_worker (void *arg, bool async) Line 521  manage_mt_worker (void *arg, bool async)
521    
522                    /* FIXME: This is inefficient.  ihash should support                    /* FIXME: This is inefficient.  ihash should support
523                       an "add if not there" function.  */                       an "add if not there" function.  */
524                    if (hurd_ihash_find (&bucket->senders, from))                    if (EXPECT_FALSE (hurd_ihash_find (&bucket->senders, from)))
525                      err = EBUSY;                      err = EBUSY;
526                    else                    else
527                      {                      {
# Line 530  manage_mt_worker (void *arg, bool async) Line 532  manage_mt_worker (void *arg, bool async)
532                  }                  }
533              }              }
534                            
535            if (err)            if (EXPECT_FALSE (err))
536              {              {
537                pthread_mutex_unlock (&bucket->lock);                pthread_mutex_unlock (&bucket->lock);
538    
# Line 568  manage_mt_worker (void *arg, bool async) Line 570  manage_mt_worker (void *arg, bool async)
570                   that we are not the current worker thread                   that we are not the current worker thread
571                   anymore.  */                   anymore.  */
572    
573                if (inhibited)                if (EXPECT_FALSE (inhibited))
574                  {                  {
575                    pthread_mutex_lock (&bucket->lock);                    pthread_mutex_lock (&bucket->lock);
576                    while (!err && bucket->state != _HURD_CAP_STATE_GREEN                    while (!err && bucket->state != _HURD_CAP_STATE_GREEN
# Line 590  manage_mt_worker (void *arg, bool async) Line 592  manage_mt_worker (void *arg, bool async)
592                    pthread_mutex_unlock (&bucket->lock);                    pthread_mutex_unlock (&bucket->lock);
593                  }                  }
594    
595                if (!err)                if (EXPECT_TRUE (!err))
596                  {                  {
597                    /* Process the message.  */                    /* Process the message.  */
598                    ctx.sender = hurd_task_id_from_thread_id (from);                    ctx.sender = hurd_task_id_from_thread_id (from);
# Line 614  manage_mt_worker (void *arg, bool async) Line 616  manage_mt_worker (void *arg, bool async)
616                   immediately follows up with a new message of course                   immediately follows up with a new message of course
617                   can expect that to work properly.  */                   can expect that to work properly.  */
618    
619                if (bucket->is_manager_waiting && !bucket->free_worker)                if (EXPECT_FALSE (bucket->is_manager_waiting
620                                    && !bucket->free_worker))
621                  {                  {
622                    /* The manager is starving for worker threads.  */                    /* The manager is starving for worker threads.  */
623                    pthread_cond_broadcast (&bucket->cond);                    pthread_cond_broadcast (&bucket->cond);
# Line 623  manage_mt_worker (void *arg, bool async) Line 626  manage_mt_worker (void *arg, bool async)
626                /* Remove from pending_rpcs (or waiting_rpcs) list.  */                /* Remove from pending_rpcs (or waiting_rpcs) list.  */
627                _hurd_cap_list_item_remove (worker);                _hurd_cap_list_item_remove (worker);
628                /* The last waiting RPC may have to signal the manager.  */                /* The last waiting RPC may have to signal the manager.  */
629                if (inhibited && bucket->state == _HURD_CAP_STATE_BLACK                if (EXPECT_FALSE (inhibited
630                    && !bucket->waiting_rpcs)                                  && bucket->state == _HURD_CAP_STATE_BLACK
631                                    && !bucket->waiting_rpcs))
632                  pthread_cond_broadcast (&bucket->cond);                  pthread_cond_broadcast (&bucket->cond);
633                _hurd_cap_list_item_add (&bucket->free_worker, worker);                _hurd_cap_list_item_add (&bucket->free_worker, worker);
634    
# Line 643  manage_mt_worker (void *arg, bool async) Line 647  manage_mt_worker (void *arg, bool async)
647                pthread_mutex_unlock (&bucket->lock);                pthread_mutex_unlock (&bucket->lock);
648    
649                /* Finally, return the reply message, if appropriate.  */                /* Finally, return the reply message, if appropriate.  */
650                if (__builtin_expect (err != ECAP_NOREPLY, 1))                if (EXPECT_TRUE (err != ECAP_NOREPLY))
651                  {                  {
652                    if (__builtin_expect (err, 0))                    if (EXPECT_FALSE (err))
653                      reply_err (from, err);                      reply_err (from, err);
654                    else                    else
655                      {                      {
# Line 665  manage_mt_worker (void *arg, bool async) Line 669  manage_mt_worker (void *arg, bool async)
669                from = manager;                from = manager;
670                msg_tag = l4_xreceive_timeout (manager, timeout, &from);                msg_tag = l4_xreceive_timeout (manager, timeout, &from);
671    
672                /* From here, we will loop all over to the beginning of                /* From here, we will loop to the beginning of the
673                   the while(1) block.  */                   while(1) block.  */
674              }              }
675          }          }
676      }      }
# Line 729  manage_mt_get_next_worker (struct worker Line 733  manage_mt_get_next_worker (struct worker
733    
734    pthread_mutex_lock (&bucket->lock);    pthread_mutex_lock (&bucket->lock);
735    
736    if (__builtin_expect (bucket->free_worker == NULL, 0))    if (EXPECT_FALSE (bucket->free_worker == NULL))
737      {      {
738        /* Slow path.  Create a new thread and use that.  */        /* Slow path.  Create a new thread and use that.  */
739        error_t err;        error_t err;
# Line 958  hurd_cap_bucket_manage_mt (hurd_cap_buck Line 962  hurd_cap_bucket_manage_mt (hurd_cap_buck
962           be true for most of the IPC operations in this file.  */           be true for most of the IPC operations in this file.  */
963        msg_tag = l4_wait_timeout (global_timeout, &from);        msg_tag = l4_wait_timeout (global_timeout, &from);
964    
965        if (__builtin_expect (l4_ipc_failed (msg_tag), 0))        if (EXPECT_FALSE (l4_ipc_failed (msg_tag)))
966          {          {
967            l4_word_t err_code = l4_error_code ();            l4_word_t err_code = l4_error_code ();
968    
# Line 1009  hurd_cap_bucket_manage_mt (hurd_cap_buck Line 1013  hurd_cap_bucket_manage_mt (hurd_cap_buck
1013            msg_tag = l4_lcall (worker);            msg_tag = l4_lcall (worker);
1014            assert (l4_ipc_succeeded (msg_tag));            assert (l4_ipc_succeeded (msg_tag));
1015    
1016            if (__builtin_expect            if (EXPECT_TRUE (l4_label (msg_tag)
1017                (l4_label (msg_tag) == _HURD_CAP_MSG_WORKER_ACCEPTED, 1))                             == _HURD_CAP_MSG_WORKER_ACCEPTED))
1018              {              {
1019                worker = manage_mt_get_next_worker (&info, &worker_thread);                worker = manage_mt_get_next_worker (&info, &worker_thread);
1020                if (worker == l4_nilthread)                if (worker == l4_nilthread)

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

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