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 <pthread.h>
>
> #include <fcntl.h>
> #include <stdio.h>
> #include <sys/file.h>
>
> 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 [EMAIL PROTECTED]
> with "unsubscribe freebsd-hackers" in the body of the message
>
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message