Changeset 96c30c8 in mainline


Ignore:
Timestamp:
2018-06-28T15:45:37Z (6 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
331d024
Parents:
82453b29
git-author:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-28 15:36:29)
git-committer:
Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-28 15:45:37)
Message:

Turn ipc_poke() into a regular wakeup on the waitq.

With prior behavior of ignoring the poke when no thread is blocking,
a thread could go to sleep just after a poke meant for it and sleep
indefinitely despite there being work to do.

After the change, worst case scenario, thread enters ipc wait, exits
immediately due to a previous poke, finds no work to do and enters ipc wait
again (possibly repeating the spurious wakeup a few times).

Location:
kernel/generic
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/synch/waitq.h

    r82453b29 r96c30c8  
    8282extern void _waitq_wakeup_unsafe(waitq_t *, wakeup_mode_t);
    8383extern void waitq_interrupt_sleep(struct thread *);
    84 extern void waitq_unsleep(waitq_t *);
    8584extern int waitq_count_get(waitq_t *);
    8685extern void waitq_count_set(waitq_t *, int val);
  • kernel/generic/src/ipc/ipc.c

    r82453b29 r96c30c8  
    550550        errno_t rc;
    551551
    552 restart:
    553552        rc = waitq_sleep_timeout(&box->wq, usec, flags, NULL);
    554553        if (rc != EOK)
     
    590589                list_append(&request->ab_link, &box->dispatched_calls);
    591590        } else {
    592                 /* This can happen regularly after ipc_cleanup */
     591                /*
     592                 * This can happen regularly after ipc_cleanup, or in
     593                 * response to ipc_poke(). Let the caller sort out the wakeup.
     594                 */
    593595                irq_spinlock_unlock(&box->lock, true);
    594                 goto restart;
     596                return NULL;
    595597        }
    596598
  • kernel/generic/src/ipc/sysipc.c

    r82453b29 r96c30c8  
    856856sys_errno_t sys_ipc_poke(void)
    857857{
    858         waitq_unsleep(&TASK->answerbox.wq);
     858        waitq_wakeup(&TASK->answerbox.wq, WAKEUP_FIRST);
    859859        return EOK;
    860860}
  • kernel/generic/src/synch/waitq.c

    r82453b29 r96c30c8  
    190190        if (do_wakeup)
    191191                thread_ready(thread);
    192 }
    193 
    194 /** Interrupt the first thread sleeping in the wait queue.
    195  *
    196  * Note that the caller somehow needs to know that the thread to be interrupted
    197  * is sleeping interruptibly.
    198  *
    199  * @param wq Pointer to wait queue.
    200  *
    201  */
    202 void waitq_unsleep(waitq_t *wq)
    203 {
    204         irq_spinlock_lock(&wq->lock, true);
    205 
    206         if (!list_empty(&wq->sleepers)) {
    207                 thread_t *thread = list_get_instance(list_first(&wq->sleepers),
    208                     thread_t, wq_link);
    209 
    210                 irq_spinlock_lock(&thread->lock, false);
    211 
    212                 assert(thread->sleep_interruptible);
    213 
    214                 if ((thread->timeout_pending) &&
    215                     (timeout_unregister(&thread->sleep_timeout)))
    216                         thread->timeout_pending = false;
    217 
    218                 list_remove(&thread->wq_link);
    219                 thread->saved_context = thread->sleep_interruption_context;
    220                 thread->sleep_queue = NULL;
    221 
    222                 irq_spinlock_unlock(&thread->lock, false);
    223                 thread_ready(thread);
    224         }
    225 
    226         irq_spinlock_unlock(&wq->lock, true);
    227192}
    228193
Note: See TracChangeset for help on using the changeset viewer.