linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: "Peter Wächtler" <pwaechtler@loewe-komp.de>
Cc: Martin.Wirth@dlr.de, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Futexes IV (Fast Lightweight Userspace Semaphores)
Date: Tue, 26 Mar 2002 12:02:06 +1100	[thread overview]
Message-ID: <E16pfLi-0001lX-00@wagner.rustcorp.com.au> (raw)
In-Reply-To: Your message of "Mon, 25 Mar 2002 12:56:36 BST." <3C9F1074.6030902@loewe-komp.de>

In message <3C9F1074.6030902@loewe-komp.de> you write:
> > 	while ((ret = uwaitq_wait(reltime)) == 0 || errno == EINTR);
> > 	uwaitq_remove(cond);
> > 	futex_down(&mutex, NULL);
> > 	return ret;
> > }
> 
> 
> I assume that uwaitq_wait() will modify the reltime (which is legal)
> if signalled. Otherwise we would wait 2*retime, and so on

Oh yeah, I'll have to split that out and handle it.  Not worth having
the kernel do it as it's hardly going to be a fast path...

> Then we have to be careful about errno and the return values:

Sigh.  Yep.  I was pretty lax...

> I assume that uwaitq_wait() will return -1 and errno==ENOENT or similar
> if we are not on the queue (anymore), -1 and ETIMEDOUT on timeout,
> -1 and EINVAL on illegal cond or reltime ,zero on wakeup?

uwaitq_wait() which does not follow a uwaitq_add() would be some kind
of error, yes.  ETIMEDOUT on timeout, yes.  EFAULT on illegal cond
(that's all it can tell, that the address isn't in the user's range),
and 0 on success.

OK, new tidier version...
Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

/* Assume we have the following operations:

   uwaitq_add(void *uaddr);
   uwaitq_remove(void *uaddr);
   uwaitq_wake(void *uaddr, int wake_all_flag);
   uwaitq_wait(relative timeout);

   And on top of them:
   futex_down(struct futex *);
   futex_up(struct futex *);
*/
typedef struct futex pthread_mutex_t;

typedef struct 
{
	int dummy; /* This could be an empty struct for gcc */
} pthread_cond_t;

typedef struct
{
	unsigned int num_left;
	unsigned int initial_count;
} pthread_barrier_t;

#define PTHREAD_MUTEX_INITIALIZER FUTEX_INITIALIZER
#define PTHREAD_COND_INITIALIZER { 0 }

int pthread_barrier_init(struct pthread_barrier_t *barrier,
			 void *addr,
			 unsigned int count)
{
	barrier->num_left = barrier->initial_count = count;
}

int pthread_barrier_wait(struct pthread_barrier_t *barrier)
{
	int ret;

	/* Use barrier address as uwaitq id. */
	ret = uwaitq_add(barrier);
	if (ret < 0)
		return ret;

	if (atomic_dec_and_test(&barrier->num_left)) {
		/* Restore barrier. */
		barrier->num_left = barrier->initial_count;
		/* Wake the other threads */
		uwaitq_wake(barrier, 1 /* WAKE_ALL */);
		uwaitq_remove(barrier);
		return 0; /* PTHREAD_BARRIER_SERIAL_THREAD */
	}
	while (uwaitq_wait(NULL) == 0 || errno == EINTR);
	uwaitq_remove(barrier);
	return 1;
}

int pthread_cond_signal(pthread_cond_t *cond)
{
	return uwaitq_wake(cond, 0 /* WAKE_ONE */);
}

int pthread_cond_broadcast(pthread_cond_t *cond)
{
	return uwaitq_wake(cond, 1 /* WAKE_ALL */);
}

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
	int ret, saved_errno;

	uwaitq_add(cond);
	futex_up(&mutex);
	while ((ret = uwaitq_wait(NULL)) == 0 || errno == EINTR);
	saved_errno = errno;
	uwaitq_remove(cond);
	futex_down(&mutex);
	errno = saved_errno;
	return ret;
}

int pthread_cond_timedwait(pthread_cond_t *cond,
			   pthread_mutex_t *mutex,
			   const struct timespec *abstime)
{
	struct timeval _now;
	struct timespec now, rel;
	int saved_errno, ret;

	/* Absolute to relative */
 again:
	gettimeofday(&_now, NULL);
	TIMEVAL_TO_TIMESPEC(&_now, &now);
	if (now.tv_sec > abstime->tv_sec
	    || (now.tv_sec == abstime->tv_sec
		&& now.tv_nsec > abstime->tv_nsec))
		return ETIMEDOUT;

	rel.tv_sec = now.tv_sec - abstime->tv_sec;
	rel.tv_nsec = now.tv_usec - abstime->tv_usec;
	if (rel.tv_nsec < 0) {
		--rel.tv_sec;
		rel.tv_nsec += 1000000000;
	}

	uwaitq_add(cond);
	futex_up(&mutex);
	ret = uwaitq_wait(&rel);
	if (ret < 0 && errno == EINTR)
		goto again;

	saved_errno = errno;
	uwaitq_remove(cond);
	futex_down(&mutex);
	errno = saved_errno;

	return ret;
}

  reply	other threads:[~2002-03-26  0:59 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-03-13  9:12 [PATCH] Futexes IV (Fast Lightweight Userspace Semaphores) Martin Wirth
2002-03-13 19:41 ` Bill Davidsen
2002-03-13 19:52   ` Dave McCracken
2002-03-13 22:17     ` Bill Davidsen
2002-03-13 20:06   ` Alan Cox
2002-03-15  7:31 ` Rusty Russell
2002-03-15  8:41   ` Martin Wirth
2002-03-15 15:29     ` Hubertus Franke
2002-03-15 16:23     ` Peter Wächtler
2002-03-16  0:12       ` Rusty Russell
2002-03-16 11:23         ` Martin Wirth
2002-03-18  0:52           ` Ulrich Drepper
2002-03-19  3:28             ` Rusty Russell
2002-03-19  4:05               ` Ulrich Drepper
2002-03-20  6:20                 ` Rusty Russell
2002-03-20 10:42                   ` Peter Wächtler
2002-03-20 17:20                     ` Ulrich Drepper
2002-03-19  8:34               ` Martin Wirth
2002-03-20  6:45                 ` Rusty Russell
2002-03-21  6:48                   ` Martin Wirth
2002-03-24 18:25                     ` Peter Wächtler
2002-03-25  2:28                       ` Rusty Russell
2002-03-25  4:46                         ` Rusty Russell
2002-03-25 11:56                           ` Peter Wächtler
2002-03-26  1:02                             ` Rusty Russell [this message]
2002-03-26  8:17                               ` Martin Wirth
2002-03-26 23:10                                 ` Rusty Russell
2002-03-27 21:05                                   ` Hubertus Franke
2002-03-27 23:53                                     ` Rusty Russell
2002-03-25  9:47                         ` Peter Wächtler
2002-03-16 19:48         ` Peter Wächtler
2002-03-17  6:50         ` Rusty Russell
  -- strict thread matches above, loose matches on Subject: below --
2002-03-05  7:01 Rusty Russell
2002-03-05 22:39 ` Davide Libenzi
2002-03-05 23:16   ` Hubertus Franke
2002-03-05 23:26     ` Davide Libenzi
2002-03-05 23:37       ` Peter Svensson
2002-03-05 23:50         ` Davide Libenzi
2002-03-08  0:07       ` Richard Henderson
2002-03-06  1:46   ` Rusty Russell
2002-03-06  2:03     ` Davide Libenzi
2002-03-08 18:07 ` Linus Torvalds
2002-03-08 19:03   ` Hubertus Franke
2002-03-08 19:22     ` Linus Torvalds
2002-03-08 20:29       ` Hubertus Franke
2002-03-08 20:48         ` Matthew Kirkwood
2002-03-08 21:02         ` Linus Torvalds
2002-03-08 23:15           ` Hubertus Franke
2002-03-08 23:36             ` Alan Cox
2002-03-08 23:41             ` Linus Torvalds
2002-03-08 23:56               ` Hubertus Franke
2002-03-09  2:12                 ` Linus Torvalds
2002-03-11 14:14                   ` Hubertus Franke
2002-03-09  0:03               ` H. Peter Anvin
2002-03-09  1:15                 ` Alan Cox
2002-03-10 19:41                   ` Linus Torvalds
2002-03-11 20:49                     ` Pavel Machek
2002-03-10 19:58                   ` Martin J. Bligh
2002-03-10 20:40                     ` Alan Cox
2002-03-10 20:28                       ` Martin J. Bligh
2002-03-10 21:05                         ` Alan Cox
2002-03-13  7:40                   ` Rusty Russell
2002-03-13 16:37                     ` Alan Cox
2002-03-12  9:35                 ` Helge Hafting
2002-03-08 20:40       ` Alan Cox
2002-03-08 20:57         ` Linus Torvalds
2002-03-08 23:43           ` H. Peter Anvin
2002-03-08 22:55         ` Hubertus Franke
2002-03-08 23:38           ` Alan Cox
2002-03-08 23:44           ` H. Peter Anvin
2002-03-08 20:47       ` george anzinger
2002-03-08 23:02         ` Hubertus Franke
2002-03-08 23:47           ` george anzinger
2002-03-09  1:11             ` Alan Cox
2002-03-09  1:20             ` Linus Torvalds
2002-03-09  4:49     ` Rusty Russell
2002-03-11 22:45       ` Linus Torvalds
2002-03-11 23:12         ` Hubertus Franke
2002-03-12  7:20         ` Rusty Russell
2002-03-12 14:56           ` Hubertus Franke
2002-03-13  4:02             ` Rusty Russell
2002-03-12 17:17           ` Linus Torvalds
2002-03-13  2:57             ` Rusty Russell
2002-03-09  4:51 ` Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E16pfLi-0001lX-00@wagner.rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=Martin.Wirth@dlr.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pwaechtler@loewe-komp.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).