Changeset bc7d44c in mainline


Ignore:
Timestamp:
2009-08-21T07:33:36Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af8e565
Parents:
b9c7425 (diff), 207e208e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge fibril synchronization improvements.

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/sysipc.h

    rb9c7425 rbc7d44c  
    5252unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec,
    5353    int nonblocking);
     54unative_t sys_ipc_poke(void);
    5455unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
    5556    unative_t method, unative_t arg1, unative_t arg2, int mode);
  • kernel/generic/include/synch/waitq.h

    rb9c7425 rbc7d44c  
    6868struct thread;
    6969
    70 extern void waitq_initialize(waitq_t *wq);
    71 extern int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, int flags);
    72 extern ipl_t waitq_sleep_prepare(waitq_t *wq);
    73 extern int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags);
    74 extern void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl);
    75 extern void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode);
    76 extern void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode);
    77 extern void waitq_interrupt_sleep(struct thread *t);
     70extern void waitq_initialize(waitq_t *);
     71extern int waitq_sleep_timeout(waitq_t *, uint32_t, int);
     72extern ipl_t waitq_sleep_prepare(waitq_t *);
     73extern int waitq_sleep_timeout_unsafe(waitq_t *, uint32_t, int);
     74extern void waitq_sleep_finish(waitq_t *, int, ipl_t);
     75extern void waitq_wakeup(waitq_t *, wakeup_mode_t);
     76extern void _waitq_wakeup_unsafe(waitq_t *, wakeup_mode_t);
     77extern void waitq_interrupt_sleep(struct thread *);
     78extern void waitq_unsleep(waitq_t *);
    7879
    7980#endif
  • kernel/generic/include/syscall/syscall.h

    rb9c7425 rbc7d44c  
    6666        SYS_IPC_FORWARD_SLOW,
    6767        SYS_IPC_WAIT,
     68        SYS_IPC_POKE,
    6869        SYS_IPC_HANGUP,
    6970        SYS_IPC_REGISTER_IRQ,
  • kernel/generic/src/ipc/sysipc.c

    rb9c7425 rbc7d44c  
    4444#include <ipc/ipcrsc.h>
    4545#include <ipc/kbox.h>
     46#include <synch/waitq.h>
    4647#include <udebug/udebug_ipc.h>
    4748#include <arch/interrupt.h>
     
    10511052}
    10521053
     1054/** Interrupt one thread from sys_ipc_wait_for_call(). */
     1055unative_t sys_ipc_poke(void)
     1056{
     1057        waitq_unsleep(&TASK->answerbox.wq);     
     1058        return EOK;
     1059}
     1060
    10531061/** Connect an IRQ handler to a task.
    10541062 *
  • kernel/generic/src/synch/waitq.c

    rb9c7425 rbc7d44c  
    171171out:
    172172        spinlock_unlock(&threads_lock);
     173        interrupts_restore(ipl);
     174}
     175
     176/** Interrupt the first thread sleeping in the wait queue.
     177 *
     178 * Note that the caller somehow needs to know that the thread to be interrupted
     179 * is sleeping interruptibly.
     180 *
     181 * @param wq            Pointer to wait queue.
     182 */
     183void waitq_unsleep(waitq_t *wq)
     184{
     185        ipl_t ipl;
     186
     187        ipl = interrupts_disable();
     188        spinlock_lock(&wq->lock);
     189
     190        if (!list_empty(&wq->head)) {
     191                thread_t *t;
     192               
     193                t = list_get_instance(wq->head.next, thread_t, wq_link);
     194                spinlock_lock(&t->lock);
     195                ASSERT(t->sleep_interruptible);
     196                if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
     197                        t->timeout_pending = false;
     198                list_remove(&t->wq_link);
     199                t->saved_context = t->sleep_interruption_context;
     200                t->sleep_queue = NULL;
     201                spinlock_unlock(&t->lock);
     202                thread_ready(t);
     203        }
     204
     205        spinlock_unlock(&wq->lock);
    173206        interrupts_restore(ipl);
    174207}
  • kernel/generic/src/syscall/syscall.c

    rb9c7425 rbc7d44c  
    137137        (syshandler_t) sys_ipc_forward_slow,
    138138        (syshandler_t) sys_ipc_wait_for_call,
     139        (syshandler_t) sys_ipc_poke,
    139140        (syshandler_t) sys_ipc_hangup,
    140141        (syshandler_t) sys_ipc_register_irq,
  • uspace/app/trace/syscalls.c

    rb9c7425 rbc7d44c  
    6262    [SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow",      3,      V_ERRNO },
    6363    [SYS_IPC_WAIT] = { "ipc_wait_for_call",             3,      V_HASH },
     64    [SYS_IPC_POKE] = { "ipc_poke",                      0,      V_ERRNO },
    6465    [SYS_IPC_HANGUP] = { "ipc_hangup",                  1,      V_ERRNO },
    6566    [SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq",      4,      V_ERRNO },
  • uspace/lib/libc/generic/async.c

    rb9c7425 rbc7d44c  
    106106
    107107atomic_t async_futex = FUTEX_INITIALIZER;
     108
     109/** Number of threads waiting for IPC in the kernel. */
     110atomic_t threads_in_ipc_wait = { 0 };
    108111
    109112/** Structures of this type represent a waiting fibril. */
     
    683686               
    684687                futex_up(&async_futex);
     688
     689                atomic_inc(&threads_in_ipc_wait);
    685690               
    686691                ipc_call_t call;
     
    688693                    SYNCH_FLAGS_NONE);
    689694               
     695                atomic_dec(&threads_in_ipc_wait);
     696
    690697                if (!callid) {
    691698                        handle_expired_timeouts();
  • uspace/lib/libc/generic/fibril_sync.c

    rb9c7425 rbc7d44c  
    4040#include <assert.h>
    4141
     42static void optimize_execution_power(void)
     43{
     44        /*
     45         * When waking up a worker fibril previously blocked in fibril
     46         * synchronization, chances are that there is an idle manager fibril
     47         * waiting for IPC, that could start executing the awakened worker
     48         * fibril right away. We try to detect this and bring the manager
     49         * fibril back to fruitful work.
     50         */
     51        if (atomic_get(&threads_in_ipc_wait) > 0)
     52                ipc_poke();
     53}
     54
    4255void fibril_mutex_initialize(fibril_mutex_t *fm)
    4356{
     
    8497                list_remove(&f->link);
    8598                fibril_add_ready((fid_t) f);
     99                optimize_execution_power();
    86100        }
    87101}
     
    152166                        fibril_add_ready((fid_t) f);
    153167                        frw->writers++;
     168                        optimize_execution_power();
    154169                        break;
    155170                } else {
     
    157172                        fibril_add_ready((fid_t) f);
    158173                        frw->readers++;
     174                        optimize_execution_power();
    159175                }
    160176        }
     
    200216                list_remove(&f->link);
    201217                fibril_add_ready((fid_t) f);
     218                optimize_execution_power();
    202219                if (once)
    203220                        break;
  • uspace/lib/libc/generic/ipc.c

    rb9c7425 rbc7d44c  
    565565}
    566566
     567/** Interrupt one thread of this task from waiting for IPC. */
     568void ipc_poke(void)
     569{
     570        __SYSCALL0(SYS_IPC_POKE);
     571}
     572
    567573/** Ask destination to do a callback connection.
    568574 *
  • uspace/lib/libc/include/async.h

    rb9c7425 rbc7d44c  
    4747extern atomic_t async_futex;
    4848
     49extern atomic_t threads_in_ipc_wait;
     50
    4951extern int __async_init(void);
    5052extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
  • uspace/lib/libc/include/ipc/ipc.h

    rb9c7425 rbc7d44c  
    192192extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int);
    193193extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t);
     194extern void ipc_poke(void);
    194195
    195196static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
Note: See TracChangeset for help on using the changeset viewer.