Update.
2004-05-18  Petter Reinholdtsen  <pere@hungry.com>

	* locales/sl_SI [LC_TIME]: Correct d_fmt date format from
	'22.06.2003' to '22. 06. 2003'.  Change requested from Aleks
	Reinhardt, and approved by the locale author Borka
	Jerman-Blazic. [BZ #163]
This commit is contained in:
Ulrich Drepper 2004-05-18 20:18:14 +00:00
parent d40eb37aad
commit 893a351195
27 changed files with 450 additions and 50 deletions

View File

@ -1,3 +1,10 @@
2004-05-18 Petter Reinholdtsen <pere@hungry.com>
* locales/sl_SI [LC_TIME]: Correct d_fmt date format from
'22.06.2003' to '22. 06. 2003'. Change requested from Aleks
Reinhardt, and approved by the locale author Borka
Jerman-Blazic. [BZ #163]
2004-05-17 Ulrich Drepper <drepper@redhat.com>
* SUPPORTED (SUPPORTED-LOCALES): Remove sr_YU locales.

View File

@ -2176,7 +2176,7 @@ mon "<U006A><U0061><U006E><U0075><U0061><U0072>";/
"<U006E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
"<U0064><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
d_fmt "<U0025><U0064><U002E><U0025><U006D><U002E><U0025><U0059>"
d_fmt "<U0025><U0064><U002E><U0020><U0025><U006D><U002E><U0020><U0025><U0059>"
t_fmt "<U0025><U0054>"
am_pm "";""
t_fmt_ampm ""

View File

@ -30,7 +30,7 @@ sub usage {
print " --help print this help, then exit\n";
print " --version print version number, then exit\n";
print "\n";
print "For bug reporting instructions, please see:\n"
print "For bug reporting instructions, please see:\n";
print "<http://www.gnu.org/software/libc/bugs.html>.\n";
exit 0;
}

View File

@ -1,3 +1,48 @@
2004-05-18 Jakub Jelinek <jakub@redhat.com>
* Makefile (.NOTPARALLEL): Only serialize make check/xcheck, not
compilation.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
(__pthread_cond_timedwait): Avoid returning -ETIMEDOUT.
* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
(pthread_cond_t): Add __data.__broadcast_seq field.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
(FRAME_SIZE): Define.
(__pthread_cond_timedwait): Use it. Store/check broadcast_seq.
Comment typo fixes.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S (FRAME_SIZE):
Define.
(__pthread_cond_wait): Use it. Store/check broadcast_seq. Comment
typo fixes.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
(__pthread_cond_broadcast): Increment broadcast_seq. Comment typo
fixes.
2004-05-18 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/lowlevelcond.sym: Add broadcast_seq entry.
* sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_cond_t):
Add __broadcast_seq field.
* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
* sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Mark
all waiters as woken with woken_seq and bump broadcast counter.
* sysdeps/pthread/pthread_cond_broadcast.c: Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Use new
__broadcast_seq field.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
* sysdeps/pthread/pthread_cond_wait.c: Likewise.
* sysdeps/pthread/pthread_cond_timedwait.c: Likewise.
* pthread_cond_init.c: Initialize __broadcast_seq field.
* Makefile (tests): Add tst-cond17 and tst-cond18.
Add .NOTPARALLEL goal.
* tst-cond16.c: New file. From Jakub.
* tst-cond17.c: New file. From Jakub.
* tst-cond18.c: New file. From Jakub.
2004-05-16 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Correct some

View File

@ -23,16 +23,30 @@ struct pthread_cond_t {
sequence number of last woken thread.
uint32_t broadcast_seq;
}
struct cv_data {
pthread_cond_t *cv;
uint32_t bc_seq
}
cleanup_handler(cv)
cleanup_handler(cv_data)
{
cv = cv_data->cv;
lll_lock(cv->lock);
++cv->wakeup_seq;
++cv->woken_seq;
if (cv_data->bc_seq == cv->broadcast_seq) {
++cv->wakeup_seq;
++cv->woken_seq;
}
/* make sure no signal gets lost. */
FUTEX_WAKE(cv->wakeup_seq, ALL);
@ -50,12 +64,14 @@ cond_timedwait(cv, mutex, timeout):
++cv->total_seq;
val = seq = cv->wakeup_seq;
cv_data.bc = cv->broadcast_seq;
cv_data.cv = cv;
while (1) {
lll_unlock(cv->lock);
enable_async
enable_async(&cv_data);
ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
@ -63,6 +79,9 @@ cond_timedwait(cv, mutex, timeout):
lll_lock(cv->lock);
if (bc != cv->broadcast_seq)
goto bc_out;
val = cv->wakeup_seq;
if (val != seq && cv->woken_seq != val) {
@ -78,6 +97,7 @@ cond_timedwait(cv, mutex, timeout):
++cv->woken_seq;
bc_out:
lll_unlock(cv->lock);
cleanup_pop
@ -105,6 +125,8 @@ cond_broadcast(cv)
if (cv->total_seq > cv->wakeup_seq) {
cv->wakeup_seq = cv->total_seq;
cv->woken_seq = cv->total_seq;
++cv->broadcast_seq;
FUTEX_WAKE(cv->wakeup_seq, ALL);
}

View File

@ -194,7 +194,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
tst-spin1 tst-spin2 tst-spin3 \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
tst-cond14 tst-cond15 \
tst-cond14 tst-cond15 tst-cond17 tst-cond18 \
tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
tst-rwlock11 tst-rwlock12 tst-rwlock13 \
@ -576,3 +576,8 @@ tst-exec4-ARGS = $(built-program-cmd)
$(objpfx)tst-execstack: $(libdl)
$(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so
LDFLAGS-tst-execstack = -Wl,-z,noexecstack
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -38,6 +38,7 @@ __pthread_cond_init (cond, cond_attr)
cond->__data.__woken_seq = 0;
cond->__data.__mutex = (icond_attr == NULL || (icond_attr->value & 1) == 0
? NULL : (void *) ~0l);
cond->__data.__broadcast_seq = 0;
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@ -40,6 +40,9 @@ __pthread_cond_broadcast (cond)
{
/* Yes. Mark them all as woken. */
cond->__data.__wakeup_seq = cond->__data.__total_seq;
cond->__data.__woken_seq = cond->__data.__total_seq;
/* Signal that a broadcast happened. */
++cond->__data.__broadcast_seq;
/* We are done. */
lll_mutex_unlock (cond->__data.__lock);

View File

@ -36,6 +36,7 @@ struct _condvar_cleanup_buffer
int oldtype;
pthread_cond_t *cond;
pthread_mutex_t *mutex;
unsigned int bc_seq;
};
int
@ -85,6 +86,8 @@ __pthread_cond_timedwait (cond, mutex, abstime)
unsigned long long int val;
unsigned long long int seq;
val = seq = cond->__data.__wakeup_seq;
/* Remember the broadcast counter. */
cbuffer.bc_seq = cond->__data.__broadcast_seq;
/* The futex syscall operates on a 32-bit word. That is fine, we
just use the low 32 bits of the sequence counter. */
@ -139,7 +142,12 @@ __pthread_cond_timedwait (cond, mutex, abstime)
}
/* Did we already time out? */
if (__builtin_expect (rt.tv_sec < 0, 0))
goto timeout;
{
if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
goto bc_out;
goto timeout;
}
/* Prepare to wait. Release the condvar futex. */
lll_mutex_unlock (cond->__data.__lock);
@ -157,6 +165,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
/* We are going to look at shared data again, so get the lock. */
lll_mutex_lock(cond->__data.__lock);
/* If a broadcast happened, we are done. */
if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
goto bc_out;
/* Check whether we are eligible for wakeup. */
val = cond->__data.__wakeup_seq;
if (val != seq && cond->__data.__woken_seq != val)
@ -178,6 +190,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
/* Another thread woken up. */
++cond->__data.__woken_seq;
bc_out:
/* We are done with the condvar. */
lll_mutex_unlock (cond->__data.__lock);

View File

@ -32,6 +32,7 @@ struct _condvar_cleanup_buffer
int oldtype;
pthread_cond_t *cond;
pthread_mutex_t *mutex;
unsigned int bc_seq;
};
@ -45,10 +46,13 @@ __condvar_cleanup (void *arg)
/* We are going to modify shared data. */
lll_mutex_lock (cbuffer->cond->__data.__lock);
/* This thread is not waiting anymore. Adjust the sequence counters
appropriately. */
++cbuffer->cond->__data.__wakeup_seq;
++cbuffer->cond->__data.__woken_seq;
if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
{
/* This thread is not waiting anymore. Adjust the sequence counters
appropriately. */
++cbuffer->cond->__data.__wakeup_seq;
++cbuffer->cond->__data.__woken_seq;
}
/* We are done. */
lll_mutex_unlock (cbuffer->cond->__data.__lock);
@ -111,6 +115,8 @@ __pthread_cond_wait (cond, mutex)
unsigned long long int val;
unsigned long long int seq;
val = seq = cond->__data.__wakeup_seq;
/* Remember the broadcast counter. */
cbuffer.bc_seq = cond->__data.__broadcast_seq;
/* The futex syscall operates on a 32-bit word. That is fine, we
just use the low 32 bits of the sequence counter. */
@ -137,6 +143,10 @@ __pthread_cond_wait (cond, mutex)
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
/* If a broadcast happened, we are done. */
if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
goto bc_out;
/* We are going to look at shared data again, so get the lock. */
lll_mutex_lock (cond->__data.__lock);
@ -148,6 +158,7 @@ __pthread_cond_wait (cond, mutex)
/* Another thread woken up. */
++cond->__data.__woken_seq;
bc_out:
/* We are done with the condvar. */
lll_mutex_unlock (cond->__data.__lock);

View File

@ -81,6 +81,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long long int __align;

View File

@ -81,6 +81,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long long int __align;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -74,6 +74,9 @@ __pthread_cond_broadcast:
woken up. */
3: movl %ecx, (%ebx)
movl %eax, 4(%ebx)
movl %ecx, woken_seq-wakeup_seq(%ebx)
movl %eax, woken_seq-wakeup_seq+4(%ebx)
addl $1, broadcast_seq-wakeup_seq(%ebx)
/* Get the address of the mutex used. */
movl dep_mutex-wakeup_seq(%ebx), %edi

View File

@ -83,15 +83,17 @@ __pthread_cond_timedwait:
addl $1, total_seq(%ebx)
adcl $0, total_seq+4(%ebx)
#define FRAME_SIZE 20
#define FRAME_SIZE 24
subl $FRAME_SIZE, %esp
.Lsubl:
/* Get and store current wakeup_seq value. */
movl wakeup_seq(%ebx), %edi
movl wakeup_seq+4(%ebx), %edx
movl broadcast_seq(%ebx), %eax
movl %edi, 12(%esp)
movl %edx, 16(%esp)
movl %eax, 20(%esp)
/* Get the current time. */
8: movl %ebx, %edx
@ -139,7 +141,8 @@ __pthread_cond_timedwait:
addl $1000000000, %edx
subl $1, %ecx
12: testl %ecx, %ecx
js 13f
movl $-ETIMEDOUT, %esi
js 6f
/* Store relative timeout. */
21: movl %ecx, 4(%esp)
@ -184,7 +187,11 @@ __pthread_cond_timedwait:
#endif
jnz 5f
6: movl woken_seq(%ebx), %eax
6: movl broadcast_seq(%ebx), %eax
cmpl 20(%esp), %eax
jne 23f
movl woken_seq(%ebx), %eax
movl woken_seq+4(%ebx), %ecx
movl wakeup_seq(%ebx), %edi
@ -203,16 +210,19 @@ __pthread_cond_timedwait:
15: cmpl $-ETIMEDOUT, %esi
jne 8b
13: addl $1, wakeup_seq(%ebx)
addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx)
movl $ETIMEDOUT, %esi
jmp 14f
23: xorl %esi, %esi
jmp 24f
9: xorl %esi, %esi
14: addl $1, woken_seq(%ebx)
adcl $0, woken_seq+4(%ebx)
LOCK
24: LOCK
#if cond_lock == 0
subl $1, (%ebx)
#else
@ -332,7 +342,8 @@ __pthread_cond_timedwait:
addl $1000000000, %edx
subl $1, %ecx
20: testl %ecx, %ecx
js 13b
movl $-ETIMEDOUT, %esi
js 6b
jmp 21b
#endif
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
@ -372,13 +383,17 @@ __condvar_tw_cleanup:
#endif
call __lll_mutex_lock_wait
1: addl $1, wakeup_seq(%ebx)
1: movl broadcast_seq(%ebx), %eax
cmpl 12(%esp), %eax
jne 3f
addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx)
addl $1, woken_seq(%ebx)
adcl $0, woken_seq+4(%ebx)
LOCK
3: LOCK
#if cond_lock == 0
subl $1, (%ebx)
#else

View File

@ -80,15 +80,17 @@ __pthread_cond_wait:
addl $1, total_seq(%ebx)
adcl $0, total_seq+4(%ebx)
#define FRAME_SIZE 12
#define FRAME_SIZE 16
subl $FRAME_SIZE, %esp
.Lsubl:
/* Get and store current wakeup_seq value. */
movl wakeup_seq(%ebx), %edi
movl wakeup_seq+4(%ebx), %edx
movl broadcast_seq(%ebx), %eax
movl %edi, 4(%esp)
movl %edx, 8(%esp)
movl %eax, 12(%esp)
/* Unlock. */
8: LOCK
@ -127,7 +129,11 @@ __pthread_cond_wait:
#endif
jnz 5f
6: movl woken_seq(%ebx), %eax
6: movl broadcast_seq(%ebx), %eax
cmpl 12(%esp), %eax
jne 16f
movl woken_seq(%ebx), %eax
movl woken_seq+4(%ebx), %ecx
movl wakeup_seq(%ebx), %edi
@ -146,7 +152,8 @@ __pthread_cond_wait:
9: addl $1, woken_seq(%ebx)
adcl $0, woken_seq+4(%ebx)
LOCK
/* Unlock */
16: LOCK
#if cond_lock == 0
subl $1, (%ebx)
#else
@ -264,13 +271,17 @@ __condvar_w_cleanup:
#endif
call __lll_mutex_lock_wait
1: addl $1, wakeup_seq(%ebx)
1: movl broadcast_seq(%ebx), %eax
cmpl 12(%esp), %eax
jne 3f
addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx)
addl $1, woken_seq(%ebx)
adcl $0, woken_seq+4(%ebx)
LOCK
3: LOCK
#if cond_lock == 0
subl $1, (%ebx)
#else

View File

@ -81,6 +81,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long int __align;

View File

@ -9,3 +9,4 @@ total_seq offsetof (pthread_cond_t, __data.__total_seq)
wakeup_seq offsetof (pthread_cond_t, __data.__wakeup_seq)
woken_seq offsetof (pthread_cond_t, __data.__woken_seq)
dep_mutex offsetof (pthread_cond_t, __data.__mutex)
broadcast_seq offsetof (pthread_cond_t, __data.__broadcast_seq)

View File

@ -101,6 +101,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long long int __align;

View File

@ -100,6 +100,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long long int __align;

View File

@ -101,6 +101,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long long int __align;

View File

@ -81,6 +81,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
long int __align;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -63,6 +63,8 @@ __pthread_cond_broadcast:
/* Cause all currently waiting threads to recognize they are
woken up. */
movq %rcx, (%rdi)
movq %rcx, woken_seq-wakeup_seq(%rdi)
incl broadcast_seq-wakeup_seq(%rdi)
/* Get the address of the mutex used. */
movq dep_mutex-wakeup_seq(%rdi), %r8
@ -110,12 +112,12 @@ __pthread_cond_broadcast:
#endif
jmp 2b
/* Unlock in loop requires waekup. */
/* Unlock in loop requires wakeup. */
5: addq $cond_lock-wakeup_seq, %rdi
callq __lll_mutex_unlock_wake
jmp 6b
/* Unlock in loop requires waekup. */
/* Unlock in loop requires wakeup. */
7: addq $cond_lock-wakeup_seq, %rdi
callq __lll_mutex_unlock_wake
subq $cond_lock-wakeup_seq, %rdi

View File

@ -51,7 +51,8 @@ __pthread_cond_timedwait:
.Lpush_r13:
pushq %r14
.Lpush_r14:
subq $80, %rsp
#define FRAME_SIZE 80
subq $FRAME_SIZE, %rsp
.Lsubq:
/* Stack frame:
@ -67,6 +68,8 @@ __pthread_cond_timedwait:
+--------------------------+
rsp + 8 | condvar pointer |
+--------------------------+
rsp + 4 | old broadcast_seq value |
+--------------------------+
rsp + 0 | old cancellation mode |
+--------------------------+
*/
@ -116,7 +119,9 @@ __pthread_cond_timedwait:
/* Get and store current wakeup_seq value. */
movq 8(%rsp), %rdi
movq wakeup_seq(%rdi), %r12
movl broadcast_seq(%rdi), %edx
movq %r12, 40(%rsp)
movl %edx, 4(%rsp)
/* Get the current time. */
8:
@ -160,7 +165,8 @@ __pthread_cond_timedwait:
decq %rcx
12: testq %rcx, %rcx
movq 8(%rsp), %rdi
js 13f
movq $-ETIMEDOUT, %r14
js 6f
/* Store relative timeout. */
21: movq %rcx, 24(%rsp)
@ -201,10 +207,15 @@ __pthread_cond_timedwait:
#endif
jne 5f
6: movq woken_seq(%rdi), %rax
6: movl broadcast_seq(%rdi), %edx
movq woken_seq(%rdi), %rax
movq wakeup_seq(%rdi), %r12
cmpl 4(%rsp), %edx
jne 23f
cmpq 40(%rsp), %r12
jbe 15f
@ -218,10 +229,13 @@ __pthread_cond_timedwait:
movq $ETIMEDOUT, %r14
jmp 14f
23: xorq %r14, %r14
jmp 24f
9: xorq %r14, %r14
14: incq woken_seq(%rdi)
LOCK
24: LOCK
#if cond_lock == 0
decl (%rdi)
#else
@ -239,7 +253,7 @@ __pthread_cond_timedwait:
testq %rax, %rax
cmoveq %r14, %rax
18: addq $80, %rsp
18: addq $FRAME_SIZE, %rsp
.Laddq:
popq %r14
.Lpop_r14:
@ -259,7 +273,7 @@ __pthread_cond_timedwait:
callq __lll_mutex_lock_wait
jmp 2b
/* Unlock in loop requires waekup. */
/* Unlock in loop requires wakeup. */
3:
#if cond_lock != 0
addq $cond_lock, %rdi
@ -278,7 +292,7 @@ __pthread_cond_timedwait:
#endif
jmp 6b
/* Unlock after loop requires waekup. */
/* Unlock after loop requires wakeup. */
10:
#if cond_lock != 0
addq $cond_lock, %rdi
@ -325,7 +339,8 @@ __pthread_cond_timedwait:
decq %rcx
20: testq %rcx, %rcx
movq 8(%rsp), %rdi
js 13b
movq $-ETIMEDOUT, %r14
js 6b
jmp 21b
#endif
.LENDCODE:
@ -394,7 +409,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.uleb128 4
.byte 0x40+.Lsubq-.Lpush_r14 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 112
.uleb128 32+FRAME_SIZE
.byte 3 # DW_CFA_advance_loc2
.2byte .Laddq-.Lsubq
.byte 14 # DW_CFA_def_cfa_offset
@ -413,7 +428,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.byte 0xcc # DW_CFA_restore %r12
.byte 0x40+.LSbl1-.Lpop_r12 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 112
.uleb128 32+FRAME_SIZE
.byte 0x8c # DW_CFA_offset %r12
.uleb128 2
.byte 0x8d # DW_CFA_offset %r13

View File

@ -61,11 +61,15 @@ __condvar_cleanup:
subq $cond_lock, %rdi
#endif
1: incq wakeup_seq(%rdi)
1: movl broadcast_seq(%rdi), %edx
cmpl 4(%r8), %edx
jne 3f
incq wakeup_seq(%rdi)
incq woken_seq(%rdi)
LOCK
3: LOCK
#if cond_lock == 0
decl (%rdi)
#else
@ -99,20 +103,23 @@ __pthread_cond_wait:
.LSTARTCODE:
pushq %r12
.Lpush_r12:
subq $64, %rsp
#define FRAME_SIZE 64
subq $FRAME_SIZE, %rsp
.Lsubq:
/* Stack frame:
rsp + 64
+--------------------------+
rsp + 32 | cleanup buffer |
+--------------------------+
+--------------------------+
rsp + 24 | old wake_seq value |
+--------------------------+
rsp + 16 | mutex pointer |
+--------------------------+
rsp + 8 | condvar pointer |
+--------------------------+
rsp + 4 | old broadcast_seq value |
+--------------------------+
rsp + 0 | old cancellation mode |
+--------------------------+
*/
@ -161,7 +168,9 @@ __pthread_cond_wait:
/* Get and store current wakeup_seq value. */
movq 8(%rsp), %rdi
movq wakeup_seq(%rdi), %r12
movl broadcast_seq(%rdi), %edx
movq %r12, 24(%rsp)
movl %edx, 4(%rsp)
/* Unlock. */
8: LOCK
@ -198,10 +207,15 @@ __pthread_cond_wait:
#endif
jnz 5f
6: movq woken_seq(%rdi), %rax
6: movl broadcast_seq(%rdi), %edx
movq woken_seq(%rdi), %rax
movq wakeup_seq(%rdi), %r12
cmpl 4(%rsp), %edx
jne 16f
cmpq 24(%rsp), %r12
jbe 8b
@ -210,7 +224,8 @@ __pthread_cond_wait:
incq woken_seq(%rdi)
LOCK
/* Unlock */
16: LOCK
#if cond_lock == 0
decl (%rdi)
#else
@ -224,7 +239,7 @@ __pthread_cond_wait:
movq 16(%rsp), %rdi
callq __pthread_mutex_cond_lock
14: addq $64, %rsp
14: addq $FRAME_SIZE, %rsp
.Laddq:
popq %r12
@ -242,7 +257,7 @@ __pthread_cond_wait:
callq __lll_mutex_lock_wait
jmp 2b
/* Unlock in loop requires waekup. */
/* Unlock in loop requires wakeup. */
3:
#if cond_lock != 0
addq $cond_lock, %rdi
@ -343,7 +358,7 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
.uleb128 2
.byte 0x40+.Lsubq-.Lpush_r12 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 80
.uleb128 16+FRAME_SIZE
.byte 2 # DW_CFA_advance_loc1
.byte .Laddq-.Lsubq
.byte 14 # DW_CFA_def_cfa_offset

105
nptl/tst-cond16.c Normal file
View File

@ -0,0 +1,105 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
bool n, exiting;
FILE *f;
int count;
void *
tf (void *dummy)
{
bool loop = true;
while (loop)
{
pthread_mutex_lock (&lock);
while (n && !exiting)
pthread_cond_wait (&cv, &lock);
n = true;
pthread_mutex_unlock (&lock);
fputs (".", f);
pthread_mutex_lock (&lock);
n = false;
if (exiting)
loop = false;
#ifdef UNLOCK_AFTER_BROADCAST
pthread_cond_broadcast (&cv);
pthread_mutex_unlock (&lock);
#else
pthread_mutex_unlock (&lock);
pthread_cond_broadcast (&cv);
#endif
}
return NULL;
}
int
do_test (void)
{
f = fopen ("/dev/null", "w");
if (f == NULL)
{
printf ("couldn't open /dev/null, %m\n");
return 1;
}
count = sysconf (_SC_NPROCESSORS_ONLN);
if (count <= 0)
count = 1;
count *= 4;
pthread_t th[count];
int i, ret;
for (i = 0; i < count; ++i)
if ((ret = pthread_create (&th[i], NULL, tf, NULL)) != 0)
{
errno = ret;
printf ("pthread_create %d failed: %m\n", i);
return 1;
}
struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 };
while (nanosleep (&ts, &ts) != 0);
pthread_mutex_lock (&lock);
exiting = true;
pthread_mutex_unlock (&lock);
for (i = 0; i < count; ++i)
pthread_join (th[i], NULL);
fclose (f);
return 0;
}
#define TEST_FUNCTION do_test ()
#define TIMEOUT 40
#include "../test-skeleton.c"

2
nptl/tst-cond17.c Normal file
View File

@ -0,0 +1,2 @@
#define UNLOCK_AFTER_BROADCAST 1
#include "tst-cond16.c"

117
nptl/tst-cond18.c Normal file
View File

@ -0,0 +1,117 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
bool exiting;
int fd, count, spins, nn;
void *
tf (void *id)
{
pthread_mutex_lock (&lock);
if ((long) id == 0)
{
while (!exiting)
{
if ((spins++ % 1000) == 0)
write (fd, ".", 1);
pthread_mutex_unlock (&lock);
pthread_mutex_lock (&lock);
int njobs = rand () % (count + 1);
nn = njobs;
if ((rand () % 30) == 0)
pthread_cond_broadcast (&cv);
else
while (njobs--)
pthread_cond_signal (&cv);
}
pthread_cond_broadcast (&cv);
}
else
{
while (!exiting)
{
while (!nn && !exiting)
pthread_cond_wait (&cv, &lock);
--nn;
pthread_mutex_unlock (&lock);
pthread_mutex_lock (&lock);
}
}
pthread_mutex_unlock (&lock);
return NULL;
}
int
do_test (void)
{
fd = open ("/dev/null", O_WRONLY);
if (fd < 0)
{
printf ("couldn't open /dev/null, %m\n");
return 1;
}
count = sysconf (_SC_NPROCESSORS_ONLN);
if (count <= 0)
count = 1;
count *= 8;
pthread_t th[count + 1];
int i, ret;
for (i = 0; i <= count; ++i)
if ((ret = pthread_create (&th[i], NULL, tf, (void *) (long) i)) != 0)
{
errno = ret;
printf ("pthread_create %d failed: %m\n", i);
return 1;
}
struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 };
while (nanosleep (&ts, &ts) != 0);
pthread_mutex_lock (&lock);
exiting = true;
pthread_mutex_unlock (&lock);
for (i = 0; i < count; ++i)
pthread_join (th[i], NULL);
close (fd);
return 0;
}
#define TEST_FUNCTION do_test ()
#define TIMEOUT 40
#include "../test-skeleton.c"