public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] Futex Generalization Patch
@ 2002-04-10 18:09 Bill Abt
  2002-04-10 18:10 ` Hubertus Franke
  0 siblings, 1 reply; 22+ messages in thread
From: Bill Abt @ 2002-04-10 18:09 UTC (permalink / raw)
  To: frankeh; +Cc: drepper, linux-kernel, Martin.Wirth, pwaechler, Rusty Russell

On 04/10/2002 at 12:37:53 PM AST, Hubertus Franke <frankeh@watson.ibm.com>
wrote:
>
> Can somebody in the thread world weight in what there preferred mechanism
is
> regarding limits etc. Do you need to control the issue on how the signal
is
> delivered? Is a file descriptor good enough or you want a sys_call
interface ?
>

I went thru the POSIX specification and couldn't find any specified limits
regarding this and in most cases these limits are enforced at the library
level.  It probably should be left up to the kernel folks to determine the
kernel limits they can live with.  The library can adapt to this value.  I
don't believe a pthread library would need any "extra" control of how the
signal is delivered.  A file descriptor is good enough, seems a waste to
have to provide a sys_call interface.

Regards,
     Bill Abt
     Senior Software Engineer
     Next Generation POSIX Threading for Linux
     IBM Cambridge, MA, USA 02142
     Ext: +(00)1 617-693-1591
     T/L: 693-1591 (M/W/F)
     T/L: 253-9938 (T/Th/Eves.)
     Cell: +(00)1 617-803-7514
     babt@us.ibm.com or abt@us.ibm.com
     http://oss.software.ibm.com/developerworks/opensource/pthreads


^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: [PATCH] Futex Generalization Patch
@ 2002-04-15 14:49 Bill Abt
  2002-04-15 16:22 ` Hubertus Franke
  0 siblings, 1 reply; 22+ messages in thread
From: Bill Abt @ 2002-04-15 14:49 UTC (permalink / raw)
  To: frankeh
  Cc: drepper, linux-kernel, Martin.Wirth, Peter Wächtler,
	Rusty Russell

Dealing with the realtime signal is not a problem.  Also, saving the extra
system call is *BIG* bonus.


Regards,
     Bill Abt
     Senior Software Engineer
     Next Generation POSIX Threading for Linux
     IBM Cambridge, MA, USA 02142
     Ext: +(00)1 617-693-1591
     T/L: 693-1591 (M/W/F)
     T/L: 253-9938 (T/Th/Eves.)
     Cell: +(00)1 617-803-7514
     babt@us.ibm.com or abt@us.ibm.com
     http://oss.software.ibm.com/developerworks/opensource/pthreads


^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: [PATCH] Futex Generalization Patch
@ 2002-04-10 19:59 Bill Abt
  2002-04-10 20:14 ` Hubertus Franke
  0 siblings, 1 reply; 22+ messages in thread
From: Bill Abt @ 2002-04-10 19:59 UTC (permalink / raw)
  To: frankeh; +Cc: drepper, linux-kernel, Martin.Wirth, pwaechtler, Rusty Russell

On 04/10/2002 at 02:47:50 PM AST, Hubertus Franke <frankeh@watson.ibm.com>
wrote:

> The current interface is
>
> (A)
> async wait:
>    sys_futex (uaddr, FUTEX_AWAIT, value, (struct timespec*) sig);
> upon signal handling
>    sys_futex(uaddrs[], FUTEX_WAIT, size, NULL);
>    to retrieve the uaddrs that got woken up...

This is actually the preferred way.  I must've misinterpeted what you said
earlier.  I believe this is actually a more generic way of handling.  A
thread package can specify the signal to used much in the way the current
LinuxThreads pre-allocates and uses certain real-time signals...

> I am mainly concerned that SIGIO can be overloaded in a thread package ?
> How would you know whether a SIGIO came from the futex or from other file

> handle.

By keep with the original interface, we don't have to contend with this
problem.  The thread package can use the signal that most suits its'
implementation...

Make sense?

Regards,
      Bill Abt
      Senior Software Engineer
      Next Generation POSIX Threading for Linux
      IBM Cambridge, MA, USA 02142
      Ext: +(00)1 617-693-1591
      T/L: 693-1591 (M/W/F)
      T/L: 253-9938 (T/Th/Eves.)
      Cell: +(00)1 617-803-7514
      babt@us.ibm.com or abt@us.ibm.com
      http://oss.software.ibm.com/developerworks/opensource/pthreads


^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: [PATCH] Futex Generalization Patch
@ 2002-04-10 19:30 Bill Abt
  2002-04-10 18:47 ` Hubertus Franke
  0 siblings, 1 reply; 22+ messages in thread
From: Bill Abt @ 2002-04-10 19:30 UTC (permalink / raw)
  To: frankeh; +Cc: drepper, linux-kernel, Martin.Wirth, pwaechtler, Rusty Russell

On 04/10/2002 at 02:10:59 PM AST, Hubertus Franke <frankeh@watson.ibm.com>
wrote:
>
> So you are OK with having only poll  or  select.  That seems odd.
> It seems you still need SIGIO on your fd to get the async notification.
>

Duh...  You're right.  I forgot about that...

Regards,
      Bill Abt
      Senior Software Engineer
      Next Generation POSIX Threading for Linux
      IBM Cambridge, MA, USA 02142
      Ext: +(00)1 617-693-1591
      T/L: 693-1591 (M/W/F)
      T/L: 253-9938 (T/Th/Eves.)
      Cell: +(00)1 617-803-7514
      babt@us.ibm.com or abt@us.ibm.com
      http://oss.software.ibm.com/developerworks/opensource/pthreads


^ permalink raw reply	[flat|nested] 22+ messages in thread
* [PATCH] Futex Generalization Patch
@ 2002-04-04  7:52 Rusty Russell
  2002-04-04 16:28 ` Hubertus Franke
  0 siblings, 1 reply; 22+ messages in thread
From: Rusty Russell @ 2002-04-04  7:52 UTC (permalink / raw)
  To: linux-kernel; +Cc: frankeh, Peter Wächtler, Martin Wirth, drepper, matthew

"This time for sure"

I have a new primitive (thanks Paul Mackerras): sleep if the word at
this address is equal to this value.  It also has an optional timeout.
On top of this, I have made pthreads locking primitives and futexes
(marginally slower than the completely-in-kernel version, but not
much).

Userspace stuff (including nonpthreads.c code):
  http://www.kernel.org/pub/linux/kernel/people/rusty/futex-2.0.tar.gz

Please complain now, or I'll send to Linus as is,
Rusty.
PS.  Will be on plane in 24 hours, for 40 hours.  Incommunicado.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5.7/include/linux/futex.h working-2.5.7-futex/include/linux/futex.h
--- linux-2.5.7/include/linux/futex.h	Thu Mar 21 14:14:54 2002
+++ working-2.5.7-futex/include/linux/futex.h	Tue Apr  2 10:56:40 2002
@@ -2,7 +2,7 @@
 #define _LINUX_FUTEX_H
 
 /* Second argument to futex syscall */
-#define FUTEX_UP (0)
-#define FUTEX_DOWN (1)
+#define FUTEX_WAIT (0)
+#define FUTEX_WAKE (1)
 
 #endif
diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/current-dontdiff --minimal linux-2.5.7/kernel/futex.c working-2.5.7-futex/kernel/futex.c
--- linux-2.5.7/kernel/futex.c	Thu Mar 21 14:14:56 2002
+++ working-2.5.7-futex/kernel/futex.c	Tue Apr  2 10:56:40 2002
@@ -32,7 +32,8 @@
 #include <linux/fs.h>
 #include <linux/futex.h>
 #include <linux/highmem.h>
-#include <asm/atomic.h>
+#include <linux/time.h>
+#include <asm/uaccess.h>
 
 /* These mutexes are a very simple counter: the winner is the one who
    decrements from 1 to 0.  The counter starts at 1 when the lock is
@@ -68,22 +69,27 @@
 	return &futex_queues[hash_long(h, FUTEX_HASHBITS)];
 }
 
-static inline void wake_one_waiter(struct list_head *head,
-				   struct page *page,
-				   unsigned int offset)
+static int futex_wake(struct list_head *head,
+		      struct page *page,
+		      unsigned int offset,
+		      int num)
 {
-	struct list_head *i;
+	struct list_head *i, *next;
+	int num_woken = 0;
 
 	spin_lock(&futex_lock);
-	list_for_each(i, head) {
+	list_for_each_safe(i, next, head) {
 		struct futex_q *this = list_entry(i, struct futex_q, list);
 
 		if (this->page == page && this->offset == offset) {
+			list_del_init(i);
 			wake_up_process(this->task);
-			break;
+			num_woken++;
+			if (num_woken >= num) break;
 		}
 	}
 	spin_unlock(&futex_lock);
+	return num_woken;
 }
 
 /* Add at end to avoid starvation */
@@ -101,11 +107,17 @@
 	spin_unlock(&futex_lock);
 }
 
-static inline void unqueue_me(struct futex_q *q)
+/* Return 1 if we were still queued (ie. 0 means we were woken) */
+static inline int unqueue_me(struct futex_q *q)
 {
+	int ret = 0;
 	spin_lock(&futex_lock);
-	list_del(&q->list);
+	if (!list_empty(&q->list)) {
+		list_del(&q->list);
+		ret = 1;
+	}
 	spin_unlock(&futex_lock);
+	return ret;
 }
 
 /* Get kernel address of the user page and pin it. */
@@ -129,74 +141,62 @@
 	return page;
 }
 
-/* Try to decrement the user count to zero. */
-static int decrement_to_zero(struct page *page, unsigned int offset)
-{
-	atomic_t *count;
-	int ret = 0;
-
-	count = kmap(page) + offset;
-	/* If we take the semaphore from 1 to 0, it's ours.  If it's
-           zero, decrement anyway, to indicate we are waiting.  If
-           it's negative, don't decrement so we don't wrap... */
-	if (atomic_read(count) >= 0 && atomic_dec_and_test(count))
-		ret = 1;
-	kunmap(page);
-	return ret;
-}
-
-/* Simplified from arch/ppc/kernel/semaphore.c: Paul M. is a genius. */
-static int futex_down(struct list_head *head, struct page *page, int offset)
+static int futex_wait(struct list_head *head,
+		      struct page *page,
+		      int offset,
+		      int val,
+		      unsigned long time)
 {
-	int retval = 0;
+	int *count;
 	struct futex_q q;
+	int ret = 0;
 
-	current->state = TASK_INTERRUPTIBLE;
+	set_current_state(TASK_INTERRUPTIBLE);
 	queue_me(head, &q, page, offset);
 
-	while (!decrement_to_zero(page, offset)) {
-		if (signal_pending(current)) {
-			retval = -EINTR;
-			break;
-		}
-		schedule();
-		current->state = TASK_INTERRUPTIBLE;
-	}
-	current->state = TASK_RUNNING;
-	unqueue_me(&q);
-	/* If we were signalled, we might have just been woken: we
-	   must wake another one.  Otherwise we need to wake someone
-	   else (if they are waiting) so they drop the count below 0,
-	   and when we "up" in userspace, we know there is a
-	   waiter. */
-	wake_one_waiter(head, page, offset);
-	return retval;
-}
-
-static int futex_up(struct list_head *head, struct page *page, int offset)
-{
-	atomic_t *count;
-
 	count = kmap(page) + offset;
-	atomic_set(count, 1);
-	smp_wmb();
+	if (*count != val) {
+		ret = -EWOULDBLOCK;
+		set_current_state(TASK_RUNNING);
+		goto out;
+	}
+	time = schedule_timeout(time);
+	if (time == 0) {
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+	if (signal_pending(current)) {
+		ret = -EINTR;
+		goto out;
+	}
+ out:
 	kunmap(page);
-	wake_one_waiter(head, page, offset);
-	return 0;
+	/* Were we woken up anyway? */
+	if (!unqueue_me(&q))
+		return 0;
+	return ret;
 }
 
-asmlinkage int sys_futex(void *uaddr, int op)
+asmlinkage int sys_futex(void *uaddr, int op, int val, struct timespec *utime)
 {
 	int ret;
 	unsigned long pos_in_page;
 	struct list_head *head;
 	struct page *page;
+	unsigned long time = MAX_SCHEDULE_TIMEOUT;
+
+	if (utime) {
+		struct timespec t;
+		if (copy_from_user(&t, utime, sizeof(t)) != 0)
+			return -EFAULT;
+		time = timespec_to_jiffies(&t) + 1;
+	}
 
 	pos_in_page = ((unsigned long)uaddr) % PAGE_SIZE;
 
 	/* Must be "naturally" aligned, and not on page boundary. */
-	if ((pos_in_page % __alignof__(atomic_t)) != 0
-	    || pos_in_page + sizeof(atomic_t) > PAGE_SIZE)
+	if ((pos_in_page % __alignof__(int)) != 0
+	    || pos_in_page + sizeof(int) > PAGE_SIZE)
 		return -EINVAL;
 
 	/* Simpler if it doesn't vanish underneath us. */
@@ -206,13 +206,12 @@
 
 	head = hash_futex(page, pos_in_page);
 	switch (op) {
-	case FUTEX_UP:
-		ret = futex_up(head, page, pos_in_page);
+	case FUTEX_WAIT:
+		ret = futex_wait(head, page, pos_in_page, val, time);
 		break;
-	case FUTEX_DOWN:
-		ret = futex_down(head, page, pos_in_page);
+	case FUTEX_WAKE:
+		ret = futex_wake(head, page, pos_in_page, val);
 		break;
-	/* Add other lock types here... */
 	default:
 		ret = -EINVAL;
 	}

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2002-04-16 20:03 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-04-10 18:09 [PATCH] Futex Generalization Patch Bill Abt
2002-04-10 18:10 ` Hubertus Franke
  -- strict thread matches above, loose matches on Subject: below --
2002-04-15 14:49 Bill Abt
2002-04-15 16:22 ` Hubertus Franke
2002-04-15 20:57   ` Mark Mielke
2002-04-15 20:46     ` Hubertus Franke
2002-04-16 20:03   ` Peter Wächtler
2002-04-10 19:59 Bill Abt
2002-04-10 20:14 ` Hubertus Franke
2002-04-11 13:55   ` Rusty Russell
2002-04-10 19:30 Bill Abt
2002-04-10 18:47 ` Hubertus Franke
2002-04-12 15:36   ` Peter Wächtler
2002-04-12 18:48     ` Hubertus Franke
2002-04-13 13:52       ` Peter Wächtler
2002-04-15 13:28         ` Hubertus Franke
2002-04-04  7:52 Rusty Russell
2002-04-04 16:28 ` Hubertus Franke
2002-04-06  9:48   ` Rusty Russell
2002-04-10 14:24     ` Hubertus Franke
2002-04-10 16:37       ` Rusty Russell
2002-04-10 16:37         ` Hubertus Franke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox