Date: Wed, 17 Jan 2001 12:29:46 -0800 (PST) From: Matt Dillon <dillon@earth.backplane.com> To: Alfred Perlstein <bright@wintelcom.net> Cc: arch@FreeBSD.ORG Subject: Re: HEADS-UP: await/asleep removal imminent Message-ID: <200101172029.f0HKTk649628@earth.backplane.com> References: <200101171138.MAA11834@freebsd.dk> <ybug0iixiee.fsf@jesup.eng.tvol.net.jesup.eng.tvol.net> <20010117092109.O7240@fw.wintelcom.net> <20010117100516.Q7240@fw.wintelcom.net> <200101171907.f0HJ7Qe48680@earth.backplane.com> <20010117112850.X7240@fw.wintelcom.net> <200101171958.f0HJwv649221@earth.backplane.com> <20010117121051.Z7240@fw.wintelcom.net>
next in thread | previous in thread | raw e-mail | index | archive | help
:> :It's not queued _anywhere_?
:>
:> Right. Not queued anywhere... the await() (or tsleep or whatever)
:> code would check for the existance of the pointer in the proc
:> structure at the time the process tries to go to sleep.
:>
:> This is why you need a condition variable... because there is no
:> way for an asynchronous event to 'wakeup' the process before it has
:> tried to go to sleep for real the process needs some way to detect
:> that the event has occured, hence the necessity of a condition
:> variable.
:>
:> The traditional tsleep/wakeup code has *NO* persistent state associated
:> with it, which means the process is required to place itself on the
:> sleep queue atomically in order to avoid the event occuring between the
:> resource allocation failure (or whatever) and the tsleep() call.
:
:I think you guys may be confused, I think you're mistaking our
:conditional variables with counting semaphores which act as sort
:of turnstiles(sp?) where you put in N tokens and only N procs can
:pass through them before blocking.
:
:The conditional variables as implemented in FreeBSD seem to only
:wake up something sleeping on them, they don't have the abilities
:you're looking for.
:
:-Alfred
Well, I haven't read the code so I don't know... what I'm saying
though is that it isn't a hard thing to do at all. If you are
going to have a persistent structure, you can have persistent state
in that structure. One of the reasons why the original asleep/await
interface is so expensive is because it is based on non-persistent
information and requires queueing from the get-go to deal with
wakeups.
Here is an example of what I am suggesting. I'll call these 'state'
variables rather then condition variables to avoid confusion:
typedef struct StateVar {
int State; /* 0= resource not avail, 1=available */
List WaitQ; /* processes waiting for 0->1 transition */
Mutex *MutexNeeded;
} StateVar;
StateVar MemState = { 1, ... , &memory_mutex };
void *
memory_allocate(int bytes, StateVar **sv)
{
Obtain memory mutex
...
if (no memory available) {
MemState.State = 0;
*sv = &MemState;
ptr = NULL; /* NULL return indicates wait condition */
}
Release memory mutex
return(ptr);
}
void
memory_free(void *ptr)
{
Obtain memory mutex
... do free operation
if (reasonable memory free based on hysteresis) {
MemState.State = 1;
WakeupWaiters(&MemState);
}
Release memory mutex
}
-------------------------------------------
somefunction()
{
StateVar *sv = NULL;
while (memory_allocate(bytes, &sv) == NULL) {
.... window of opportunity where some other process may
release enough memory to set State variable to 1.
This case is handled by the implementation .....
await(sv); /* or await(&sv) and await sets it to NULL */
sv = NULL;
}
}
----------------------------------------------
await(StateVar *sv)
{
if (sv->State == 0) {
ObtainMutex(sv->sv_MutexNeeded);
while (sv->State == 0) {
Enqueue process on sv->WaitQ
Go to sleep for real
}
ReleaseMutex(sv->sv_MutexNeeded);
}
}
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?200101172029.f0HKTk649628>
