PROCESS_SHARED mutexes and rwlocks do not work
| 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;
}