Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Apr 1997 03:17:55 +0200 (MET DST)
From:      "Alex Fenyo (eowyn)" <fenyo@email.enst.fr>
To:        freebsd-hackers@FreeBSD.org
Cc:        jb@cimlogic.com.au
Subject:   Scheduling with libc_r...
Message-ID:  <199704230117.DAA21364@nikopol.enst.fr>

next in thread | raw e-mail | index | archive | help

Hi,

[ I continue my investigations on fd locking :) This time,
I have a problem with fd locking and scheduling ]

After having read some parts of libc_r (and performed a little test),
I think there is a strange behaviour in the scheduling algorithm (a
solution is suggested at the end of this mail).

Suppose we have two threads.

The first one performs a read system call on a file descriptor, and
LATER, the second one performs a read system call on the same file
descriptor too.

Suppose that the priority of the first thread is lower than the
priority of the second thread.

So, we have 2 waiting threads : the low priority thread called read
before the high priority thread.

The problem is that when something will be able to be read, the low
priority thread will run first, before the high priority one.

This is because the low priority thread performed a lock on the
filedescriptor before the high priority thread.
Thus, the low priority thread was in state PS_FDR, and the
other one in state PS_FD_LR.

When the data arrives on the file descriptor, _thread_kern_sched()
changes the state PS_FDR to PS_RUNNING. But it does nothing with
threads in state PS_FD_LR.
Then, the low priority thread is scheduled. It finishes the
read call by unlocking the filedescriptor (and then the
high priority thread state changes from PS_FD_LR to PS_FDR,
but the low priority thread continues to run).

I think this strange behaviour can be simply corrected
by adding a call to _thread_kern_sched() at the end
of _thread_fd_unlock in uthread_fd.c.

Just modify uthread_fd_unlock() (src/lib/libc_r uthread_fd.c) :
------------------------------------------------------------
        /* Unblock signals again: */
        _thread_kern_sig_unblock(status);

        /* Nothing to return. */
        return;
}
------------------------------------------------------------
by this :
------------------------------------------------------------
        /* Unblock signals again: */
        _thread_kern_sig_unblock(status);

        _thread_kern_sched(NULL);

        /* Nothing to return. */
        return;
}
------------------------------------------------------------

It is important to note that the high priority thread must
return first from the system call, BUT moreover, it must have
read the data first (during the system call). It is done,
with the modification I suggest. But only because a side effect
is that the low priority thread returns EAGAIN.

Thanks,
Alexandre Fenyo



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704230117.DAA21364>