lkml.org 
[lkml]   [2009]   [Feb]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC git tree] Userspace RCU (urcu) for Linux (repost)
    * Paul E. McKenney (paulmck@linux.vnet.ibm.com) wrote:
    > On Sat, Feb 07, 2009 at 07:10:28AM -0800, Paul E. McKenney wrote:
    > > So, how to fix? Here are some approaches:
    > >
    > > o Make urcu_publish_content() do two parity flips rather than one.
    > > I use this approach in my rcu_rcpg, rcu_rcpl, and rcu_rcpls
    > > algorithms in CodeSamples/defer.
    > >
    > > o Use a single free-running counter, in a manner similar to rcu_nest,
    > > as suggested earlier. This one is interesting, as I rely on a
    > > read-side memory barrier to handle the long-preemption case.
    > > However, if you believe that any thread that waits several minutes
    > > between executing adjacent instructions must have been preempted
    > > (which the memory barriers that are required to do a context
    > > switch), then a compiler barrier suffices. ;-)
    > >
    > > Of course, the probability of seeing this failure during test is quite
    > > low, since it is unlikely that thread 0 would run just long enough to
    > > execute its signal handler. However, it could happen. And if you were
    > > to adapt this algorithm for use in a real-time application, then priority
    > > boosting could cause this to happen naturally.
    >
    > And here is a patch, taking the first approach. It also exposes a
    > synchronize_rcu() API that is used by the existing urcu_publish_content()
    > API. This allows easier handling of structures that are referenced by
    > more than one pointer. And should also allow to be more easily plugged
    > into my rcutorture test. ;-)
    >

    Merged, thanks !

    Mathieu

    > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    > ---
    >
    > urcu.c | 39 ++++++++++++++++++++++++++-------------
    > 1 file changed, 26 insertions(+), 13 deletions(-)
    >
    > diff --git a/urcu.c b/urcu.c
    > index e401d8d..1a276ce 100644
    > --- a/urcu.c
    > +++ b/urcu.c
    > @@ -113,13 +113,35 @@ void wait_for_quiescent_state(int parity)
    > force_mb_all_threads();
    > }
    >
    > +static void switch_qparity(void)
    > +{
    > + int prev_parity;
    > +
    > + /* All threads should read qparity before accessing data structure. */
    > + /* Write ptr before changing the qparity */
    > + force_mb_all_threads();
    > + prev_parity = switch_next_urcu_qparity();
    > +
    > + /*
    > + * Wait for previous parity to be empty of readers.
    > + */
    > + wait_for_quiescent_state(prev_parity);
    > +}
    > +
    > +void synchronize_rcu(void)
    > +{
    > + rcu_write_lock();
    > + switch_qparity();
    > + switch_qparity();
    > + rcu_write_unlock();
    > +}
    > +
    > /*
    > * Return old pointer, OK to free, no more reference exist.
    > * Called under rcu_write_lock.
    > */
    > void *urcu_publish_content(void **ptr, void *new)
    > {
    > - int prev_parity;
    > void *oldptr;
    >
    > /*
    > @@ -134,19 +156,10 @@ void *urcu_publish_content(void **ptr, void *new)
    > */
    > oldptr = *ptr;
    > *ptr = new;
    > - /* All threads should read qparity before ptr */
    > - /* Write ptr before changing the qparity */
    > - force_mb_all_threads();
    > - prev_parity = switch_next_urcu_qparity();
    >
    > - /*
    > - * Wait for previous parity to be empty of readers.
    > - */
    > - wait_for_quiescent_state(prev_parity);
    > - /*
    > - * Deleting old data is ok !
    > - */
    > -
    > + switch_qparity();
    > + switch_qparity();
    > +
    > return oldptr;
    > }
    >
    >

    --
    Mathieu Desnoyers
    OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68


    \
     
     \ /
      Last update: 2009-02-08 01:23    [W:0.035 / U:0.056 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site