lkml.org 
[lkml]   [2007]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[rfc][patch] futex: restartable futex_wait?
    Hi Ingo,

    I'm seeing an LTP test fail for ltp test sigaction_16_24. Basically,
    it tests whether the SA_RESTART flag works for the sem_wait operation.

    I see sem_wait is implemented with futex_wait, so I wonder whether we
    can make it restartable? Am I going about it the right way? (Seems to
    fix the testcase here).

    Thanks,
    Nick

    --
    Index: linux-2.6/kernel/futex.c
    ===================================================================
    --- linux-2.6.orig/kernel/futex.c
    +++ linux-2.6/kernel/futex.c
    @@ -978,6 +978,7 @@ static void unqueue_me_pi(struct futex_q
    drop_futex_key_refs(&q->key);
    }

    +static long futex_wait_restart(struct restart_block *restart);
    static int futex_wait(u32 __user *uaddr, u32 val, unsigned long time)
    {
    struct task_struct *curr = current;
    @@ -1077,11 +1078,22 @@ static int futex_wait(u32 __user *uaddr,
    return 0;
    if (time == 0)
    return -ETIMEDOUT;
    +
    /*
    * We expect signal_pending(current), but another thread may
    * have handled it for us already.
    */
    - return -EINTR;
    + if (time == MAX_SCHEDULE_TIMEOUT)
    + return -ERESTARTSYS;
    + else {
    + struct restart_block *restart;
    + restart = &current_thread_info()->restart_block;
    + restart->fn = futex_wait_restart;
    + restart->arg0 = (unsigned long)uaddr;
    + restart->arg1 = (unsigned long)val;
    + restart->arg2 = time;
    + return -ERESTART_RESTARTBLOCK;
    + }

    out_unlock_release_sem:
    queue_unlock(&q, hb);
    @@ -1091,6 +1103,17 @@ static int futex_wait(u32 __user *uaddr,
    return ret;
    }

    +static long futex_wait_restart(struct restart_block *restart)
    +{
    + u32 __user *uaddr = (u32 __user *)restart->arg0;
    + u32 val = (u32)restart->arg1;
    + unsigned long time = restart->arg2;
    +
    + restart->fn = do_no_restart_syscall;
    + return (long)futex_wait(uaddr, val, time);
    +}
    +
    +
    /*
    * Userspace tried a 0 -> TID atomic transition of the futex value
    * and failed. The kernel side here does the whole locking operation:
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-03-07 16:37    [W:0.020 / U:5.388 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site