From owner-freebsd-hackers Wed Jul 18 11:40:29 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from InterJet.elischer.org (c421509-a.pinol1.sfba.home.com [24.7.86.9]) by hub.freebsd.org (Postfix) with ESMTP id ABF6A37B406 for ; Wed, 18 Jul 2001 11:40:23 -0700 (PDT) (envelope-from julian@elischer.org) Received: from InterJet.elischer.org (InterJet.elischer.org [192.168.1.1]) by InterJet.elischer.org (8.9.1a/8.9.1) with ESMTP id NAA95051; Wed, 18 Jul 2001 13:24:54 -0700 (PDT) Date: Wed, 18 Jul 2001 13:24:53 -0700 (PDT) From: Julian Elischer To: Louis-Philippe Gagnon Cc: freebsd-hackers@FreeBSD.ORG, Stephane Lussier Subject: Re: flock/pthread bug? In-Reply-To: <1f9c01c10fb5$3d4ba770$2964a8c0@macadamian.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG probably you should try : #define LOCK_NB 0x04 /* don't block when locking */ Also if you have shared memory, why not use /* Get a spin lock, handle recursion inline (as the less common case) */ #define _getlock_spin_block(mtxp, tid, type) ({ \ int _res = MTX_UNOWNED; \ \ __asm __volatile ( \ " pushfl;" \ " cli;" \ " " MPLOCKED "" \ " cmpxchgl %3,%1;" /* Try */ \ " jz 2f;" /* got it */ \ " pushl %4;" \ " pushl %5;" \ " call mtx_enter_hard;" /* mtx_enter_hard(mtxp, type, oflags) */ \ " addl $12,%%esp;" \ " jmp 1f;" \ "2: popl %2;" /* save flags */ \ "1:" \ "# getlock_spin_block" \ : "+a" (_res), /* 0 */ \ "+m" (mtxp->mtx_lock), /* 1 */ \ "=m" (mtxp->mtx_savecrit) /* 2 */ \ : "r" (tid), /* 3 (input) */ \ "gi" (type), /* 4 */ \ "g" (mtxp) /* 5 */ \ : "cc", "memory", "ecx", "edx" /* used */ ); \ }) (or similar) taken from -current /sys/i386/include/mutex.h. the key is the cmpxchgl instruction. use the cvsweb interface to explore these instructions. (also look at atomic.h I think) On Wed, 18 Jul 2001, Louis-Philippe Gagnon wrote: > Hi, > > I've been looking for a way to get inter-process synchronization between multithreaded processes. (I need synchronized access to > an area of shared memory between multiple instances of the same process) > > Since I was using SysV shared memory, I had first thought of using SysV semaphores for synchronization; however, the functions > semop, semctl (etc) don't seem to be pthread-aware, so that if a semop() call blocks, the entire process is blocked instead of > only the calling thread. > > I then looked at the pthread mutexes, but it looks like the FreeBSD implementation doesn't support PTHREAD_PROCESS_SHARED (at > least in 4.3-release; has this changed in -stable or -current?) > > Then I found out about the flock() function; the man page mentions a different implementation for threaded and non-threaded > libraries, so I though this would work with pthreads. > > This does not appear to be the case. If one program locks a file with flock(LOCK_EX), the next program that tries to lock will be > suspended completely, instead of only the calling thread. > > Given this program : > > #include > > #include > #include > #include > > void *printf_thread(void *p) > { > while(1) > printf("#"); > } > > void main(void) > { > pthread_t t; > int fd; > > fd = open("lockfile",O_WRONLY|O_CREAT, 0666); > pthread_create(&t,NULL,printf_thread,NULL); > flock(fd,LOCK_EX); > pthread_join(t,NULL); > } > > (program opens a file, launches a thread (which calls printf() endlessly), locks the file and waits for ^C) > > The first instance launched will print an infinity of #'s from its printf_thread > The second instance (launced from the sae directory, to use the same lock file) will not print anything until the first intance is > killed. Since the printf_thread is launched before the flock() call, I expected it to keep running while the main thread blocks; > instead, both threads apear to be blocked. > > (I tried on Linux (RH6.1), the program behaves as I expected) > > I tried another test before this one (don't have the source anymore, I overwrote the same file), which used only one instance of > the program, with 2 threads trying to lock the file > I expected something like this : > thread 1 locks the file > thread 2 tries to lock the file, blocks > thread 1 unlocks the file > thread 2 gets file lock and unblocks > > Instead I got > thread 1 locks the file > thread 2 tries to lock the file, whole process blocks > (thread 1 is blocked, can't unlock the file : deadlock) > > So : > -Is flock() supposed to block the whole process? > -Is my test program wrong? > -Does this look like a bug in libc_r? > -Is there a better (working) way of getting interprocess synchronization in multithreaded programs? > > Thanks. > > Louis-Philippe Gagnon > > ps. should I submit problem reports immediately in cases like this, or wait for people's opinions first? > > > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-hackers" in the body of the message > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message