PROCESS_SHARED mutexes and rwlocks do not work

[email protected]
Newsgroups gmane.linux.ngpt.devel
Message-ID <[email protected]>
Hi Bill and others,

I did try the attached test proglet on 2.0.0 and patched 2.4.19 UP 
kernel.
It does not work as expected on Linux - but on Irix ;-)

Now I tried against 2.0.1:
gcc -D_REENTRANT -o locktest lock.c /usr/lib/libpthread.so

a) use of mutexes between processes

Once a process got the lock - it uses it exclusivly?
If I use the program without -f fork() on two terminals, just one 
process makes progress.
You can use higher numbers for -n to see that only one process makes 
progress and the others starve and never get the lock!
This is a really weird one:

peewee@lancelot:/tmp> ./locktest -i
sizeof(pthread_mutex_t):24
sizeof(pthread_rwlock_t):4
sizeof(shmstruct):32
initialize shmem with ftruncate
pthread_mutex_init(SHARED) returns: 0
pthread_rwlock_init(SHARED) returns: 0

peewee@lancelot:/tmp> ./locktest -m -ff -n2
sizeof(pthread_mutex_t):24
sizeof(pthread_rwlock_t):4
sizeof(shmstruct):32
I am   : pid 1937
created: pid 1938
created: pid 1939
  1937:pthread_mutex_lock
  1937:mutex is now locked
  1939:pthread_mutex_lock
  1938:pthread_mutex_lock
  1937:pthread_mutex_unlock:3
  1937:pthread_mutex_lock
  1937:mutex is now locked
  1937:pthread_mutex_unlock:4
peewee@lancelot:/tmp>  1939:mutex is now locked
  1939:pthread_mutex_unlock:5
  1939:pthread_mutex_lock
  1939:mutex is now locked
  1939:pthread_mutex_unlock:6

peewee@lancelot:/tmp> ps ux
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
peewee     858  0.0  0.6  5704 2432 pts/1    S    00:03   0:00 -bash
peewee    1832  0.0  0.6  5676 2396 pts/3    S    00:36   0:00 -bash
peewee    1876  0.0  0.6  5700 2416 pts/2    S    00:41   0:00 -bash
peewee    1938  2.7  0.1  1752  764 pts/3    S    00:45   0:01 
./locktest -m -ff -n
peewee    1939  8.3  0.0     0    0 pts/3    Z    00:45   0:04 [locktest 
<defunct>]
peewee    1942  0.0  0.3  2484 1500 pts/3    R    00:46   0:00 ps ux
peewee@lancelot:/tmp> cat /proc/1939/status
Name:   locktest
State:  Z (zombie)
Tgid:   1939
Pid:    1939
PPid:   1938
TracerPid:      0
Uid:    501     501     501     501
Gid:    105     105     105     105
FDSize: 0
Groups: 105 14 16 17 33
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000


On an Irix system:

peewee:/tmp:>./sgilock -m -ff -n2
sizeof(pthread_mutex_t):32
sizeof(pthread_rwlock_t):64
sizeof(shmstruct):100
I am   : pid 3456
created: pid 3452
  3456:pthread_mutex_lock
  3456:mutex is now locked
  3453:pthread_mutex_lock
created: pid 3453
  3452:pthread_mutex_lock
  3456:pthread_mutex_unlock:1
  3456:pthread_mutex_lock
  3453:mutex is now locked
  3453:pthread_mutex_unlock:2
  3453:pthread_mutex_lock
  3453:mutex is now locked
  3453:pthread_mutex_unlock:3
  3456:mutex is now locked
  3456:pthread_mutex_unlock:4
  3452:mutex is now locked
peewee:/tmp:> 3452:pthread_mutex_unlock:5
  3452:pthread_mutex_lock
  3452:mutex is now locked
  3452:pthread_mutex_unlock:6


b) use of rwlocks between processes:

./testlock -r	# the first one succeeds, shmem was initialized (like -i)
./testlock -r         # results in SEGV but
./testlock -sr       # survives - just inserted a sleep before the first 
use of rwlock (huh?)


Then in the RELEASE file there is a MAXNATIVETHREAD env var mentioned, 
it has to be MAXNATIVETHREADS
In patch-futex-2.4.19-2.0.1 there is a huge chunk of 
drivers/scsi/sim710_d.h - who is working on this? ;-) It's a generated 
file - you can use the dontdiff file
lock.c (text/plain, 3.7 KB)
#define _XOPEN_SOURCE 600

#include <pthread.h>

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>

#include <libgen.h>

#define SHMEMNAME "lock_test"

struct shmstruct {
	pthread_mutex_t mutex;
	pthread_rwlock_t rwlock;
	int count;
};
struct shmstruct *ptr;
int crash=0;
int sleep_hack=0;

int simple_rwlock()
{
	if (sleep_hack)
		sleep(1);
	fprintf(stderr,"%5d:pthread_rwlock_wrlock\n",getpid());
	pthread_rwlock_wrlock(&ptr->rwlock);
	fprintf(stderr,"%5d:rwlock is now locked\n",getpid());

	sleep(3);
	if (crash){
		char *p=NULL;

		fprintf(stderr,"crashing...%c\n",*p);
	}
	ptr->count++;

	fprintf(stderr,"%5d:pthread_rwlock_unlock:%d\n",getpid(),ptr->count);
	pthread_rwlock_unlock(&ptr->rwlock);

	return 0;
}

int simple_mutex()
{
	fprintf(stderr,"%5d:pthread_mutex_lock\n",getpid());
	pthread_mutex_lock(&ptr->mutex);
	fprintf(stderr,"%5d:mutex is now locked\n",getpid());

	sleep(3);
	if (crash){
		char *p=NULL;

		fprintf(stderr,"crashing...%c\n",*p);
	}
	ptr->count++;

	fprintf(stderr,"%5d:pthread_mutex_unlock:%d\n",getpid(),ptr->count);
	pthread_mutex_unlock(&ptr->mutex);

	return 0;
}

int init_shmem(int fd)
{
	int i;
	pthread_mutexattr_t mattr;
	pthread_rwlockattr_t rwattr;
	
	fprintf(stderr,"initialize shmem with ftruncate\n");
	ftruncate(fd, sizeof(struct shmstruct) );
	pthread_mutexattr_init(&mattr);
	pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
	i=pthread_mutex_init(&ptr->mutex, &mattr);
	fprintf(stderr,"pthread_mutex_init(SHARED) returns: %d\n",i);
	pthread_mutexattr_destroy(&mattr);
	if (i != 0 ){
		errno=i;
		perror("pthread_mutex_init");
		shm_unlink(SHMEMNAME);
		return 1;
	}
	pthread_rwlockattr_init(&rwattr);
	pthread_rwlockattr_setpshared(&rwattr, PTHREAD_PROCESS_SHARED);
	i=pthread_rwlock_init(&ptr->rwlock, &rwattr);
	fprintf(stderr,"pthread_rwlock_init(SHARED) returns: %d\n",i);
	pthread_rwlockattr_destroy(&rwattr);
	if (i != 0 ){
		errno=i;
		perror("pthread_rwlock_init");
		shm_unlink(SHMEMNAME);
		return 1;
	}
	ptr->count=0;
	return 0;
}

int main(int argc, char **argv)
{
	int fd,i,dofork=0,domutex=1,n=1;
	
	i=0;
	if ((fd=shm_open(SHMEMNAME, O_RDWR|O_CREAT|O_EXCL, 
		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0){

		if (errno==EEXIST){
			if ((fd=shm_open(SHMEMNAME, O_RDWR, 0)) < 0){
				perror("shm_open");
				exit(1);
			}
		} else {
			perror("shm_open");
			exit(1);
		}
	} else
		i=1;
		
	ptr = mmap(NULL, sizeof(struct shmstruct), 
		PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

	if (ptr == MAP_FAILED  ){
		perror("mmap failed");
		return 1;
	}
	if (i)
	 	if (init_shmem(fd))
			exit(1);

	fprintf(stderr,"sizeof(pthread_mutex_t):%d\n",sizeof(pthread_mutex_t));
	fprintf(stderr,"sizeof(pthread_rwlock_t):%d\n",sizeof(pthread_rwlock_t));
	fprintf(stderr,"sizeof(shmstruct):%d\n",sizeof(struct shmstruct));
	
	while ((i=getopt(argc,argv,"icuxrmfn:s"))!= -1){
		switch (i){
		case 'u':
			fprintf(stderr,"pthread_mutex_unlock\n");
			pthread_mutex_unlock(&ptr->mutex);
			exit(0);
			break;
		case 'c':
			crash=1;break;
		case 'i':
			return init_shmem(fd);
			break;
		case 'x':
			fprintf(stderr,"FD: closing(%d)\n",fd);
			close(fd);
			break;
		case 'r':
			domutex=0;
			break;
		case 'm':
			domutex=1;
			break;
		case 'f':
			dofork++;
			break;
		case 'n':
			n=strtol(optarg,NULL,10);
			break;
		case 's':
			sleep_hack=1;
			break;
		}
	}

	fprintf(stderr,"I am   : pid %d\n",getpid());
	while (dofork >0 ){
	
		switch ((i=fork()) ){
			case -1:
				perror("fork");
				exit(1);
			case 0:
				break;
			default:
				fprintf(stderr,"created: pid %d\n",i);
				dofork=0;
		}
		dofork--;
	}

	while (n > 0){	
		if (domutex)
			simple_mutex();
		else
			simple_rwlock();
		n--;
	}
	return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.