Re: preemptive kernel

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

 



howdy,

> this code already breaks even without a non-preemptible kernel.....
> your use of *_sleep_on() is defective.

oops sorry.

> You, probably, want wait_event_interruptible().

I'll try :)

> Is this code supposed to be race-condition-free and to be working on
> multiprocessing environments?  If so, you should consider using atomic
> instructions like mutexes and semaphores....

well I was not thinking about the SMP part (apologies).
previous code obviously doesn't work if under SMP. 
let me try rephrase one more time:

1) is exclusive access policy basically okay like the below
   under SMP and/or PREEMPTIVE kernel? [I also want to sleep
   until some conditions are met]
2) how does the kernel support existing old code (eg., drivers)
   which assumes non-preemptive kernel behavior even under
   preemptive option enabled? 
   Or, ...said differently, does being 'SMP aware' automatically 
   imply 'preemptive-kernel ready'? (if so, plase disregard
   rest of my message)

--
static wait_queue_head_t q;
static int some_flag = 0;    /* condition variable of some sort */
static int lock = 0;         /* lock for critical section */

static ssize_t 
my_write(struct file * file, const char * buf,
                       size_t count, loff_t *ppos)
{
    while (1) {
      if ((error = wait_event_interruptible(q, !some_flag)) < 0) {
        retval = error;
        goto out;
      }
#if SMP_OR_PREEMPTIVE  /* = !(UNI_processor && NONPREEMPTIVE) */
      if (!test_and_set_bit(0, &lock)) {  /* samaphore equally okay, atomic_inc_and_test() and such, too */
        if (!some_flag) {
          some_flag = 1;
          break;
        }
        else
          test_and_clear_bit(0, &lock);
      }
#else
      some_flag = 1; break;
#endif
    }

    <...access shared resource assuming exclusive access...>

#if SMP_OR_PREEMPTIVE  /* = !(UNI_processor && NONPREEMPTIVE) */
    test_and_clear_bit(0, &lock); /* just clear_bit() instead? */
#endif
    wake_up_interruptible_all(&q); /* tell some_flag has changed */
out:
    return retval;
}
--

regads,
kenji
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux