Skip to content

Commit

Permalink
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S:
Browse files Browse the repository at this point in the history
	(__pthread_rwlock_rdlock): Don't use non SH-3/4 instruction.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S:
	(__pthread_rwlock_wrlock): Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S:
	(pthread_rwlock_timedrdlock): Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S:
	(pthread_rwlock_timedwrlock): Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S:
	(__pthread_rwlock_unlock): Likewise.

2007-06-10  Kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* sysdeps/sh/tcb-offsets.sym: Add PRIVATE_FUTEX.
	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Include endian.h.
	Split __flags into __flags, __shared, __pad1 and __pad2.
	* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Use private
        futexes if they are available.
	* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Adjust so that change
        in libc-lowlevellock.S allow using private futexes.
	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define
	FUTEX_PRIVATE_FLAG.  Add additional parameter to lll_futex_wait,
	lll_futex_timed_wait and lll_futex_wake.  Change lll_futex_wait
	to call lll_futex_timed_wait.  Add lll_private_futex_wait,
	lll_private_futex_timed_wait and lll_private_futex_wake.
	(lll_robust_mutex_unlock): Fix typo.
	* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Use private
        field in futex command setup.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Use
	COND_NWAITERS_SHIFT instead of COND_CLOCK_BITS.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_once.S: Use private futexes
        if they are available.  Remove clear_once_control.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Use private
	futexes if they are available.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/sem_post.S: Add private futex support.
	Wake only when there are waiters.
	* sysdeps/unix/sysv/linux/sh/sem_wait.S: Add private futex
	support.  Indicate that there are waiters.  Remove unnecessary
        extra cancellation test.
	* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise.  Removed
	left-over duplication of __sem_wait_cleanup.
  • Loading branch information
Ulrich Drepper committed Jun 17, 2007
1 parent e0d4a4e commit 339dbf0
Show file tree
Hide file tree
Showing 18 changed files with 800 additions and 200 deletions.
49 changes: 49 additions & 0 deletions nptl/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,52 @@
2007-06-17 Kaz Kojima <kkojima@rr.iij4u.or.jp>

* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S:
(__pthread_rwlock_rdlock): Don't use non SH-3/4 instruction.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S:
(__pthread_rwlock_wrlock): Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S:
(pthread_rwlock_timedrdlock): Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S:
(pthread_rwlock_timedwrlock): Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S:
(__pthread_rwlock_unlock): Likewise.

2007-06-10 Kaz Kojima <kkojima@rr.iij4u.or.jp>

* sysdeps/sh/tcb-offsets.sym: Add PRIVATE_FUTEX.
* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Include endian.h.
Split __flags into __flags, __shared, __pad1 and __pad2.
* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Use private
futexes if they are available.
* sysdeps/unix/sysv/linux/sh/lowlevellock.S: Adjust so that change
in libc-lowlevellock.S allow using private futexes.
* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Define
FUTEX_PRIVATE_FLAG. Add additional parameter to lll_futex_wait,
lll_futex_timed_wait and lll_futex_wake. Change lll_futex_wait
to call lll_futex_timed_wait. Add lll_private_futex_wait,
lll_private_futex_timed_wait and lll_private_futex_wake.
(lll_robust_mutex_unlock): Fix typo.
* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Use private
field in futex command setup.
* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Use
COND_NWAITERS_SHIFT instead of COND_CLOCK_BITS.
* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_once.S: Use private futexes
if they are available. Remove clear_once_control.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Use private
futexes if they are available.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
* sysdeps/unix/sysv/linux/sh/sem_post.S: Add private futex support.
Wake only when there are waiters.
* sysdeps/unix/sysv/linux/sh/sem_wait.S: Add private futex
support. Indicate that there are waiters. Remove unnecessary
extra cancellation test.
* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise. Removed
left-over duplication of __sem_wait_cleanup.

2007-06-07 Ulrich Drepper <drepper@redhat.com>

* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Add additional
Expand Down
3 changes: 3 additions & 0 deletions nptl/sysdeps/sh/tcb-offsets.sym
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads)
TLS_PRE_TCB_SIZE sizeof (struct pthread)
MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
#ifndef __ASSUME_PRIVATE_FUTEX
PRIVATE_FUTEX offsetof (struct pthread, header.private_futex)
#endif
19 changes: 17 additions & 2 deletions nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
Expand All @@ -20,6 +21,8 @@
#ifndef _BITS_PTHREADTYPES_H
#define _BITS_PTHREADTYPES_H 1

#include <endian.h>

#define __SIZEOF_PTHREAD_ATTR_T 36
#define __SIZEOF_PTHREAD_MUTEX_T 24
#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
Expand Down Expand Up @@ -127,9 +130,21 @@ typedef union
unsigned int __writer_wakeup;
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned char __pad1;
unsigned char __pad2;
unsigned char __shared;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned char __flags;
#else
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
unsigned char __flags;
unsigned char __shared;
unsigned char __pad1;
unsigned char __pad2;
#endif
pthread_t __writer;
} __data;
char __size[__SIZEOF_PTHREAD_RWLOCK_T];
Expand Down
30 changes: 29 additions & 1 deletion nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
Expand All @@ -16,4 +16,32 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

#include <kernel-features.h>

/* All locks in libc are private. Use the kernel feature if possible. */
#define FUTEX_PRIVATE_FLAG 128
#ifdef __ASSUME_PRIVATE_FUTEX
# define FUTEX_WAIT (0 | FUTEX_PRIVATE_FLAG)
# define FUTEX_WAKE (1 | FUTEX_PRIVATE_FLAG)
#else
# define LOAD_FUTEX_WAIT(reg,tmp) \
stc gbr, tmp ; \
mov.w 99f, reg ; \
add reg, tmp ; \
bra 98f ; \
mov.l @tmp, reg ; \
99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
98:
# define LOAD_FUTEX_WAKE(reg,tmp) \
stc gbr, tmp ; \
mov.w 99f, reg ; \
add reg, tmp ; \
mov.l @tmp, reg ; \
bra 98f ; \
mov #FUTEX_WAKE, tmp ; \
99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
98: or tmp, reg
#endif

#include "lowlevellock.S"
31 changes: 25 additions & 6 deletions nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,24 @@

#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#ifndef FUTEX_WAIT
# define FUTEX_WAIT 0
# define FUTEX_WAKE 1
#endif

#ifndef LOAD_FUTEX_WAIT
# if FUTEX_WAIT == 0
# define LOAD_FUTEX_WAIT(reg,tmp) \
xor reg, reg
# else
# define LOAD_FUTEX_WAIT(reg,tmp) \
mov #FUTEX_WAIT, reg; \
extu.b reg, reg
# endif
# define LOAD_FUTEX_WAKE(reg,tmp) \
mov #FUTEX_WAKE, reg; \
extu.b reg, reg
#endif


.globl __lll_mutex_lock_wait
Expand All @@ -40,7 +56,7 @@ __lll_mutex_lock_wait:
mov r4, r6
mov r5, r8
mov #0, r7 /* No timeout. */
mov #FUTEX_WAIT, r5
LOAD_FUTEX_WAIT (r5, r0)

mov #2, r4
cmp/eq r4, r6
Expand Down Expand Up @@ -133,7 +149,7 @@ __lll_mutex_timedlock_wait:
bt 8f

mov r8, r4
mov #FUTEX_WAIT, r5
LOAD_FUTEX_WAIT (r5, r0)
mov r10, r6
mov r15, r7
mov #SYS_futex, r3
Expand Down Expand Up @@ -192,7 +208,7 @@ __lll_mutex_timedlock_wait:
.align 5
cfi_startproc
__lll_mutex_unlock_wake:
mov #FUTEX_WAKE, r5
LOAD_FUTEX_WAKE (r5, r0)
mov #1, r6 /* Wake one thread. */
mov #0, r7
mov.l r7, @r4 /* Stores 0. */
Expand Down Expand Up @@ -261,7 +277,10 @@ __lll_timedwait_tid:
bt 4f

mov r8, r4
mov #FUTEX_WAIT, r5
/* XXX The kernel so far uses global futex for the wakeup at
all times. */
mov #0, r5
extu.b r5, r5
mov r2, r6
mov r15, r7
mov #SYS_futex, r3
Expand Down
85 changes: 78 additions & 7 deletions nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,22 @@
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
#include <kernel-features.h>

#define SYS_futex 240
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
#define FUTEX_PRIVATE_FLAG 128


/* Values for 'private' parameter of locking macros. Yes, the
definition seems to be backwards. But it is not. The bit will be
reversed before passing to the system call. */
#define LLL_PRIVATE 0
#define LLL_SHARED FUTEX_PRIVATE_FLAG


/* Initializer for compatibility lock. */
Expand Down Expand Up @@ -251,7 +260,7 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
and %2,%0\n\
mov.l %0,@%1\n\
1: mov r1,r15"\
: "=&r" (__result) : "r" (__futex), "r" (FUTEX_TID_MASK) \
: "=&r" (__result) : "r" (__futex), "r" (FUTEX_WAITERS) \
: "r0", "r1", "memory"); \
if (__result) \
__lll_mutex_unlock_wake (__futex); })
Expand All @@ -269,7 +278,7 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
1: mov r1,r15"\
: "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
: "r0", "r1", "memory"); \
lll_futex_wake (__futex, 1); })
lll_futex_wake (__futex, 1, 0); })

#define lll_mutex_islocked(futex) \
(futex != 0)
Expand All @@ -294,14 +303,56 @@ typedef int lll_lock_t;
trapa #0x14"
# endif

#define lll_futex_wait(futex, val) \
#define lll_futex_wait(futex, val, private) \
lll_futex_timed_wait (futex, val, NULL, private)


#define lll_futex_timed_wait(futex, val, timeout, private) \
({ \
int __status; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
register unsigned long __r5 asm ("r5") = FUTEX_WAIT; \
register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
register unsigned long __r7 asm ("r7") = (timeout); \
__asm __volatile (SYSCALL_WITH_INST_PAD \
: "=z" (__status) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
"r" (__r6), "r" (__r7) \
: "memory", "t"); \
__status; \
})


#define lll_futex_wake(futex, nr, private) \
do { \
int __ignore; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
register unsigned long __r5 asm ("r5") = FUTEX_WAKE; \
register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
register unsigned long __r7 asm ("r7") = 0; \
__asm __volatile (SYSCALL_WITH_INST_PAD \
: "=z" (__ignore) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
"r" (__r6), "r" (__r7) \
: "memory", "t"); \
} while (0)


#define lll_private_futex_wait(futex, val) \
lll_private_futex_timed_wait (futex, val, NULL)


#ifdef __ASSUME_PRIVATE_FUTEX
# define lll_private_futex_timed_wait(futex, val, timeout) \
({ \
int __status; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
register unsigned long __r5 asm ("r5") = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; \
register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
register unsigned long __r7 asm ("r7") = (timeout); \
__asm __volatile (SYSCALL_WITH_INST_PAD \
: "=z" (__status) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
Expand All @@ -311,14 +362,32 @@ typedef int lll_lock_t;
})


#define lll_futex_timed_wait(futex, val, timeout) \
# define lll_private_futex_wake(futex, nr) \
do { \
int __ignore; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
register unsigned long __r5 asm ("r5") = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; \
register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
register unsigned long __r7 asm ("r7") = 0; \
__asm __volatile (SYSCALL_WITH_INST_PAD \
: "=z" (__ignore) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
"r" (__r6), "r" (__r7) \
: "memory", "t"); \
} while (0)


#else
# define lll_private_futex_timed_wait(futex, val, timeout) \
({ \
int __status; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
register unsigned long __r5 asm ("r5") = FUTEX_WAIT; \
register unsigned long __r5 asm ("r5"); \
register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
register unsigned long __r7 asm ("r7") = (timeout); \
__r5 = THREAD_GETMEM (THREAD_SELF, header.private_futex); \
__asm __volatile (SYSCALL_WITH_INST_PAD \
: "=z" (__status) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
Expand All @@ -328,20 +397,22 @@ typedef int lll_lock_t;
})


#define lll_futex_wake(futex, nr) \
# define lll_private_futex_wake(futex, nr) \
do { \
int __ignore; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
register unsigned long __r5 asm ("r5") = FUTEX_WAKE; \
register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
register unsigned long __r7 asm ("r7") = 0; \
__r5 |= THREAD_GETMEM (THREAD_SELF, header.private_futex); \
__asm __volatile (SYSCALL_WITH_INST_PAD \
: "=z" (__ignore) \
: "r" (__r3), "r" (__r4), "r" (__r5), \
"r" (__r6), "r" (__r7) \
: "memory", "t"); \
} while (0)
#endif


/* The states of a lock are:
Expand All @@ -367,7 +438,7 @@ extern int __lll_wait_tid (int *tid) attribute_hidden;
do { \
__typeof (tid) *__tid = &(tid); \
while (*__tid != 0) \
lll_futex_wait (__tid, *__tid); \
lll_futex_wait (__tid, *__tid, 0); \
} while (0)

extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
Expand Down
10 changes: 9 additions & 1 deletion nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -65,7 +65,13 @@ pthread_barrier_wait:
#if CURR_EVENT != 0
add #CURR_EVENT, r4
#endif
#if FUTEX_WAIT == 0
mov.l @(PRIVATE,r8), r5
#else
mov #FUTEX_WAIT, r5
mov.l @(PRIVATE,r8), r0
or r0, r5
#endif
mov #0, r7
8:
mov #SYS_futex, r3
Expand Down Expand Up @@ -118,6 +124,8 @@ pthread_barrier_wait:
#endif
mov #0, r7
mov #FUTEX_WAKE, r5
mov.l @(PRIVATE,r8), r0
or r0, r5
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
Expand Down
Loading

0 comments on commit 339dbf0

Please sign in to comment.