This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[aegl@unix-os.sc.intel.com] libc/2223: _pthread_lock sometimes spins uselessly



Hi glibc folks,

please comment on the appended bug report.  Should we really change
_pthread_fastlock to:

struct _pthread_fastlock
{
  volatile long int __status;   /* "Free" or "taken" or head of waiting list */
  int __spinlock;      /* Used by compare_and_swap emulation. Also,
			  adaptive SMP lock stores spin count here. */
};

Andreas



>Number:         2223
>Category:       libc
>Synopsis:       _pthread_lock sometimes spins uselessly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    libc-gnats
>State:          open
>Quarter:        
>Keywords:       
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Mon Apr 30 14:05:01 -0400 2001
>Cases:          
>Originator:     Tony Luck
>Release:        libc-2.2.1
>Organization:
 Intel
>Environment:
	machine: 2-cpu ia64
	os: linux 2.4.3
Host type: ia64-redhat-linux-gnu
System: Linux selsey.sc.intel.com 2.4.3 #3 SMP Thu Apr 19 16:31:11 PDT 2001 ia64 unknown
Architecture: ia64

Addons: c_stubs linuxthreads
Build CFLAGS: -DNDEBUG=1 -g -O3
Build CC: gcc
Compiler version: 2.96-ia64-000717 snap 001117
Kernel headers: 2.4.0-0.99.11
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: yes
Build omitfp: no
Build bounded: no
Build static-nss: no
Stdio: libio

>Description:
	The "__status" field of the _pthread_fastlock structure is not
	declared with volatile storage type.  Thus the compiler may
	optimize references to this location outside the loop in
	_pthread_lock, causing the processor to spin checking the value
	in a register, instead of in memory.
>How-To-Repeat:
	Run 3 copies of this program on a 4-way machine. Observe %CPU using
	"top" and notice that sometimes one process of a pair will consume
	100% of a cpu, while its partner gets zero cpu time.
/*
 * how fast can we context switch?
 */

#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/time.h>

sem_t s1, s2;

volatile unsigned long pingloops;

void *ping(void *a)
{
	for (;;) {
		pingloops++;
		sem_wait(&s1);
		sem_post(&s2);
	}
}

void *pong(void *a)
{
	for (;;) {
		sem_wait(&s2);
		sem_post(&s1);
	}
}

int
main(int argc, char **argv)
{
	pthread_t tid;
	struct timeval now, then;
	unsigned long lastloops;
	double sec;


	sem_init(&s1, 0, 1);
	sem_init(&s2, 0, 0);

	pthread_create(&tid, NULL, ping, NULL);
	pthread_create(&tid, NULL, pong, NULL);


	gettimeofday(&then, 0);
	lastloops = pingloops;
	for (;;) {
		sleep(5);
		gettimeofday(&now, 0);
		sec = (now.tv_sec - then.tv_sec) +
			(now.tv_usec - then.tv_usec) / 1.0e6;
		printf("loopspersec=%.1f\n", (pingloops-lastloops)/sec);
		then = now;
		lastloops = pingloops;
	}
	return 0;
}
>Fix:
	In linuxthreads/sysdeps/pthread/bits/pthreadtypes.h make the __status
	element of the _pthread_fastlock structure volatile.






-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]