Two IA-64 Linux bugs
System info:
[nspr@tl2 unix]$ uname -a
Linux tl2.compile.sourceforge.net 2.3.99-pre6-000501-18smp #1 SMP Sat May 6 21:30:48 PDT 2000 ia64 unknown
Bug #1: pthread_cond_wait sometimes returns EINVAL (22). Run the first attachment (pingpong.c) repeatedly. Note that this test doesn't call pthread_cond_destroy so it is impossible that we are waiting on a destroyed condition variable. This failure is intermittent so you may need to try many times to reproduce it.
Bug #2: sysconf(_SC_NPROCESSORS_ONLN) returns 0. It should return the number of processors online. Run the second attachment (ncpus.c) to reproduce it.
Wan-Teh
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define LOOP 20000
int toggle = 0; /* either 0 or 1 */ pthread_mutex_t mutex; /* protects 'toggle' */ pthread_cond_t cond; /* for the threads to wait on */
void *ping(void *arg)
{
int i;
int rv;
rv = pthread_mutex_lock(&mutex);
if (rv) {
fprintf(stderr, "pthread_mutex_lock failed: %d\n", rv);
exit(1);
}
for (i = 0; i < LOOP; i++) {
while (toggle == 0) {
rv = pthread_cond_wait(&cond, &mutex);
if (rv) {
fprintf(stderr, "pthread_cond_wait failed: %d\n", rv);
exit(1);
}
}
toggle--;
rv = pthread_cond_signal(&cond);
if (rv) {
fprintf(stderr, "pthread_cond_signal failed: %d\n", rv);
exit(1);
}
}
rv = pthread_mutex_unlock(&mutex);
if (rv) {
fprintf(stderr, "pthread_mutex_unlock failed: %d\n", rv);
exit(1);
}
return NULL;
}void *pong(void *arg)
{
int i;
int rv;
rv = pthread_mutex_lock(&mutex);
if (rv) {
fprintf(stderr, "pthread_mutex_lock failed: %d\n", rv);
exit(1);
}
for (i = 0; i < LOOP; i++) {
while (toggle == 1) {
rv = pthread_cond_wait(&cond, &mutex);
if (rv) {
fprintf(stderr, "pthread_cond_wait failed: %d\n", rv);
exit(1);
}
}
toggle++;
rv = pthread_cond_signal(&cond);
if (rv) {
fprintf(stderr, "pthread_cond_signal failed: %d\n", rv);
exit(1);
}
}
rv = pthread_mutex_unlock(&mutex);
if (rv) {
fprintf(stderr, "pthread_mutex_unlock failed: %d\n", rv);
exit(1);
}
return NULL;
}int main()
{
pthread_attr_t attr;
pthread_t t1, t2;
int rv;
rv = pthread_mutex_init(&mutex, NULL);
if (rv) {
fprintf(stderr, "pthread_mutex_init failed: %d\n", rv);
exit(1);
}
rv = pthread_cond_init(&cond, NULL);
if (rv) {
fprintf(stderr, "pthread_cond_init failed: %d\n", rv);
exit(1);
}
rv = pthread_attr_init(&attr);
if (rv) {
fprintf(stderr, "pthread_attr_init failed: %d\n", rv);
exit(1);
}
rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (rv) {
fprintf(stderr, "pthread_attr_setdetachstate failed: %d\n", rv);
exit(1);
}
rv = pthread_create(&t1, &attr, ping, NULL);
if (rv) {
fprintf(stderr, "pthread_create failed: %d\n", rv);
exit(1);
}
rv = pthread_create(&t2, &attr, pong, NULL);
if (rv) {
fprintf(stderr, "pthread_create failed: %d\n", rv);
exit(1);
}
rv = pthread_join(t1, NULL);
if (rv) {
fprintf(stderr, "pthread_join failed: %d\n", rv);
exit(1);
}
rv = pthread_join(t2, NULL);
if (rv) {
fprintf(stderr, "pthread_join failed: %d\n", rv);
exit(1);
}
return 0;
}#include <stdio.h>
#include <unistd.h>
int main()
{
printf("# processors online = %d\n", sysconf(_SC_NPROCESSORS_ONLN));
return 0;
}Quoted 7 lines · Wan-Teh Chang
System info:
[nspr@tl2 unix]$ uname -a
Linux tl2.compile.sourceforge.net 2.3.99-pre6-000501-18smp #1 SMP Sat May 6 21:30:48 PDT 2000 ia64 unknownBug #2:
sysconf(_SC_NPROCESSORS_ONLN)returns 0.
It should return the number of processors online.
I've fixed that in the "official" glibc tree one week ago. It's been fixed in HJ's tree a few weeks ago (but I don't know how he did it).
This is implemented by counting the lines starting with "CPU#" in /proc/cpuinfo. If the kernel guys change the format of that file, it might break again.
Dan
Quoted 6 lines · Dan Pop
I've fixed that in the "official" glibc tree one week ago. It's been fixed in HJ's tree a few weeks ago (but I don't know how he did it).
This is implemented by counting the lines starting with "CPU#" in
/proc/cpuinfo. If the kernel guys change the format of that file, it might break again.
Is there any reason why this reads /proc/cpuinfo and not /proc/stat? /proc/stat is at least consistent across architectures...
Bill
Quoted 8 lines · Bill Nottingham
Quoted 4 lines · Dan Pop
This is implemented by counting the lines starting with "CPU#" in
/proc/cpuinfo. If the kernel guys change the format of that file, it might break again.Is there any reason why this reads
/proc/cpuinfoand not/proc/stat?/proc/statis at least consistent across architectures...
The right person to answer this question is the glibc maintainer, who happens to be a colleague of yours :-)
Dan
We also had problems around here with pthread_cond_wait. The glibc version we were using was used a linuxthreads snapshot taken at a bad time. Pthread_cond_wait checked that the current thread owned the mutex. Unfortunately, it did so even for "fast" mutexes, for which the owner field wasn't set.
If this is the problem, I would guess that you should be able to avoid it by using recursive or checking mutexes. The problem is hopefully very temporary, since the glibc on sourceware exhibited this problem for only a day.
Hans
Quoted 7 lines
Bug #1:
pthread_cond_waitsometimes returns EINVAL (22). Run the first attachment (pingpong.c) repeatedly. Note that this test doesn't callpthread_cond_destroyso it is impossible that we are waiting on a destroyed condition variable. This failure is intermittent so you may need to try many times to reproduce it.
Quoted 11 lines · Hans
We also had problems around here with
pthread_cond_wait. The glibc version we were using was used a linuxthreads snapshot taken at a bad time.Pthread_cond_waitchecked that the current thread owned the mutex. Unfortunately, it did so even for "fast" mutexes, for which the owner field wasn't set.If this is the problem, I would guess that you should be able to avoid it by using recursive or checking mutexes. The problem is hopefully very temporary, since the glibc on sourceware exhibited this problem for only a day.
Indeed, if I use a recursive or error-checking mutex, I cannot make my test case (pingpong.c) fail.
Wan-Teh