Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Aug 2002 16:42:55 -0700 (PDT)
From:      Julian Elischer <julian@elischer.org>
To:        arch@freebsd.org
Subject:   Process/thread states.
Message-ID:  <Pine.BSF.4.21.0208261603020.83598-100000@InterJet.elischer.org>

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

Ok so I've mentionned this to a few peopel at different times and not got
any real feedback/pushback.. time fopr a wider audience.

Lookingf at teh states that a thread can be in, I've come to teh
conclusion that it;s not really just one easy set of states, but a graph
which includes 2 and posssibly 3 independent orthogonal componets.

One of my aims during teh KSE changes was to make the td_state
variable truely represent the state of the thread when not under the sched
lock. (Under Schedlock there can be transitional inconsitancies).


However the more I look at it I see that what used to be a simple
selection of:
SSLEEP
SRUN
SSTOP
SINTR

is really a tremdous simplification, and often incorrect.
The state is suplementted by such things as:
the non-NULL-ness of th wchan field
and other information regarding the swap state.
As a result of this, many places that wnat to make a decision based on
state of the thread (was process in 4.x) need to make extra
tests which are easy to leave out..

e.g. 
something like:

if ((td->td_state == TDS_RUNQ) && (td->td_wchan == NULL))

This is how you see if the thread is on teh run queue but not on the sleep
queue.. yet teh fact that td->td_wchan == NULL isn a rather unintuative
way of suplementing the state to discover if the process/thread
is sleeping, especially if later on the test becomes

if (td->td_state == TDS_SLP)

If the test is REALLY (td->td_wchan != NULL)
 then why bother having a state SSLEEP  (or TDS_SLP) at all?

the best answer I think is to extent the state definitions to include
the possibility of some orthogonal components..

e.g. something like: (yeah I know its messy but...):


 
#define TD_ST_SUSPQ        0x01    /* uses runq field */
#define TD_ST_RUNQ         0x02    /* uses runq field */
#define TD_ST_RUNNING      0x03    /* uses no (virtual) field */
#define TD_ST_MTX          0x04    /* uses mtx field */
#define TD_ST_RQ_MASK      0x07    /* mask of non sleep states */
#define TD_ST_SLPQ         0x08    /* uses slpq field */
enum thread_state {
        TDS_UNQUEUED    = 0x00,
        TDS_SLP         = TD_ST_SLPQ,
        TDS_RUNQ        = TD_ST_RUNQ,
        TDS_RUNNING     = TD_ST_RUNNING,
        TDS_SUSPENDED   = TD_ST_SUSPQ,
        TDS_MTX         = TD_ST_MTX,
        TDS_SUSP_SLP    = TD_ST_SUSPQ|TD_ST_SLPQ,
        TDS_RUN_SLP     = TD_ST_RUNNING|TD_ST_SLPQ,
        TDS_RUNQ_SLP    = TD_ST_RUNQ|TD_ST_SLPQ, 
        TDS_MTX_SLP     = TD_ST_MTX|TD_ST_SLPQ,
        TDS_SWAPPING    = TD_ST_SLPQ|TD_ST_RQ_MASK + 1,
        TDS_IWAIT,	/* needed? */
        TDS_SURPLUS	/* needed? */
};

this is becasue it is quite legal for the thread to be on the suspended
queue AND on the sleep queue.. (!) this happens during msleep (and the CV
code) and NOT under the sched lock either.. During this time the process
can be 'awakened' by a 'wakeup()' which will take it off the sleep queue
so that when the suspension ends, the thread does not continue into teh
full sleep, but instead returns. Similarly, the thread can be on the
sleep queue AND on the run queue, or even on the sleep queue but actually
running. All outside of the protection of the schedlock.

By allowing code to set and clear jsut the bit that represents the
presense on teh sleep queue, teh sorrect state can be maintained,
and the thread state can actually be used to make decisions. 
It is possible that the SWAPPING state may be expanded in a similar manner
as well. (I haven't really examined it recently)

I think the following thread state components are mutually exclusive:

On the run queue.
Actually running.
On the processes suspend queue.
On a mutex's blocked queue.

orthognal to those might be::
On the sleep queue. (which can and does occur while in the above states)
Not Fully swapped in, (which MAY (not sure yet) occur to a thread
that is a in at least one of the basic states, and the sleep state).

I'm not sure if TDS_IWAIT is needed any more and TDS_SURPLUS can pretty
surely go
away I think.


anyway..
I'm, puting this out in -arch because I'm sure this would create howls of
complaint from people if I "just did it". It seems to me 
that it may clean up quirte a bit of code around the sleeping and
suspension parts of the system, and remove some "traps for young players"
(I ran into one last week hence this RFC).

over to you guys.. Particularly those who HATE the idea.


p.s. for bonus points: could the mutex blocked chain be implemented using
the linkage field in teh thread struct already used by the suspend and run
queues, since they are all  (I think) mutually exclusive..?



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0208261603020.83598-100000>