[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [bluetooth-dev] SDP problem...



> -----Original Message-----
> From: Maksim Krasnyanskiy [mailto:maxk@xxxxxxx.com]
> Sent: Monday, June 25, 2001 20:35
> To: Peter Kjellerstedt; 'david LIBAULT'
> Cc: bluetooth-dev@xxxxxxx.com
> Subject: RE: [bluetooth-dev] SDP problem...
> 
> > >       cli();
> > >       if (database_query.count <= 0) {
> > >               D_PROC(__FUNCTION__ " No bytes available, going to sleep\n");
> > >               interruptible_sleep_on(&database_wq);
> > >       }
> > >       sti();
> >  
> > > So when sdp_server tries to read the sdp_proc file, all 
> > > interrupts are disabled, and then it goes to sleep right?
> > > So, no more interrupts can happen. I don't understand
> > > this piece of code (I'm sorry).
> >
> >interruptible_sleep_on() enables interrupts while it is 
> waiting, and disables them again before returning.
> Nop, it doesn't. 

I beg to differ (to a certain extent).
This is the code for interruptible_sleep_on() in 2.0.38
(which we are currently using) with my comments:

static inline void __sleep_on(struct wait_queue **p, int state)
{
        unsigned long flags;
        struct wait_queue wait = { current, NULL };

        if (!p)
                return;
        if (current == task[0])
                panic("task[0] trying to sleep");
        current->state = state;
        save_flags(flags);              // save the current irq state
        cli();
        __add_wait_queue(p, &wait);
        sti();                          // now interrupts are enabled
        schedule();                     // again while we schedule
        cli();
        __remove_wait_queue(p, &wait);
        restore_flags(flags);	          // now we are back where we
                                        // started, with or without
                                        // interrupts enabled
}

void interruptible_sleep_on(struct wait_queue **p)
{
        __sleep_on(p,TASK_INTERRUPTIBLE);
}

Basically, the same thing happens below with the help of
wq_write_lock_irqsave() and wq_write_unlock_irqrestore(),
which also stores and restores the irq state.

BUT: I am not sure what happens if the code at the start
of this mail is run on an SMP machine. It is possible that
only the processor that executes the interruptible_sleep_on()
function gets interrupts enabled. I cannot decipher the
2.4 code well enough to tell what happens in this case. :(

> #define SLEEP_ON_HEAD                                   \
>          wq_write_lock_irqsave(&q->lock,flags);          \
>          __add_wait_queue(q, &wait);                     \
>          wq_write_unlock(&q->lock);
> 
> #define SLEEP_ON_TAIL                                           \
>          wq_write_lock_irq(&q->lock);                            \
>          __remove_wait_queue(q, &wait);                          \
>          wq_write_unlock_irqrestore(&q->lock,flags);
> 
> void interruptible_sleep_on(wait_queue_head_t *q)
> {
>          SLEEP_ON_VAR
> 
>          current->state = TASK_INTERRUPTIBLE;
> 
>          SLEEP_ON_HEAD
>          schedule();
>          SLEEP_ON_TAIL
> }
> 
> Name interruptible has nothing to do with hardware 
> interrupts.  It just mean that sleep can 
> be interrupted by the signal.
> 
> Max

Using cli()/sti() is probably a bad idea, and had we initially
written the code for 2.2 or 2.4 I suppose spinlocks would have
been used instead. But as far as I know, spinlocks haven't been
backported (or rather emulated) for 2.0...

//Peter
-
To unsubscribe from this list: send the line "unsubscribe bluetooth-dev" in
the body of a message to majordomo@xxxxxxx.com