Skip site navigation (1)Skip section navigation (2)
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>