2013/11/4 LRN <lrn1...@gmail.com>

> What CreateSemaphore() uses internally is anyone's guess. It might be
> CreateFileMapping(), it might be not. If it goes into kernel side,
> then it may as well use something more efficient there.
> libwinpthreads uses CreateSemaphore() internally, so if you'd use the
> semaphore API that winpthreads provides you with, it might just work.
> This is basically a recap of my original message.
> If winpthreads shared semaphores didn't work for you (i.e. they
> weren't shared as you hoped they would be), that's another matter
> (maybe worth fixing, maybe not). From the paragraph above it's not
> clear whether you tested them at all.
>

So let me explain myself a bit more. The libtubo code runs fine on Linux
and BSD and I've been using it for years now. First on Xffm (xfce-4.0 and
xfce-4.2 filemanager) and now on the Rodent Filemanager. The code uses
semaphores between two HW processes and between several LW processes
(threads). These are unnamed semaphores (memory-based semaphores) for
performance considerations. From man page:

#include <semaphore.h>

 An  unnamed  semaphore  does not have a name.  Instead the sema‐
              phore is placed in a region of memory  that  is  shared
between
              multiple  threads  (a  thread-shared  semaphore) or processes
(a
              process-shared semaphore).  A thread-shared semaphore is
placed
              in  an  area  of memory shared between the threads of a
process,
              for example, a global variable.  A process-shared semaphore
must
              be  placed  in  a  shared memory region (e.g., a System V
shared
              memory segment created using shmget(2), or a POSIX shared
memory
              object built created using shm_open(3))

This is all fine in Linux. In BSD (last time I checked) unnamed memory
based process-shared semaphores are not supported. That is, unnamed memory
based semaphores between HWP. Unnamed memory based semaphores
(thread-shared) work fine. But since BSD supports <sys/mman.h>, hacking a
memory based semaphore between HWP's is not difficult.

So now we come to Mingw and Windows. Here there's  no <sys/mmap.h> (at
least my configure script did not find one). My initial question, refrased
more adequately, would be: are unnamed  memory-based process-shared
semaphores possible (without much ado)? Answer, probably not. You gotta use
named semaphores, at least with the CreateSemaphore.  And you can't
initialize an unnamed semaphore in shared memory because ---even though
*CreateFileMapping*<http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx>
(*INVALID_HANDLE_VALUE*) seems like a shm_open equivalent--- there is no
function equivalent to mmap() to actually map that shared memory to a data
structure. On this last point, I believe there probably is a function that
does the mmap() trick, but this I could not find. And I wouldn't be
surprised if that function is part of the stuff MS does not disclose.

That's the picture in my head at this moment, it's not written in stone.

By all lights, unnamed thread-shared semaphores should work out of the box
with <semaphore.h>, or so I thought.

So now let's get to the tests I did and what I bumped into. I was working
against the clock to port an application from Linux to Windows so I just
hacked up a simple named semaphore for the HWP process interaction and
supposed that the unnamed thread-shared semaphore would work just fine.

But no, it crashed. I looked into using the CreateSemaphore function
instead of <semaphore.h>, but the more I looked, the more stuff I would
have to change. So I took the safe route and opted for pthread
mutex/condition control.


> >
> > 2- Local semaphores (shared only between threads). Posix
> > semaphores in Mingw seem to be subject to race conditions not
> > present in Linux or FreeBSD. When I tried to use them in Windows,
> > libtubo would crash. So I replaced these  semaphores with pthread
> > conditions and things worked just fine.
> Do you have any good backtraces? Testcases? If 'Posix semaphores in
> Mingw' means 'winpthreads', then ktietz will be interested in
> eliminating that race condition, i bet.
>

I'm not sure if the semaphores defined in <semaphore.h> (which I called
Posix semaphores in Mingw) also means 'winpthreads'. I suppose they could,
but I'm not familiar with what gcc does to implement <semaphore.h> and what
it puts into pthreadGC2.dll.

You can download the testcase (included in libtubo) with
git clone git://git.code.sf.net/p/xffm/tubo xffm-tubo

After you generate the build scripts with autogen.sh and run configure and
make, you get a program "example.exe". This is a console app which queries
you for a command to execute.  It works fine in Windows.

But if you export CFLAGS=-DUSE_SEMAPHORES before ./configure or uncomment
the relevant line in tubo_exec.c and recompile,  then program will crash in
Windows, and in Windows only. This is the example crash giving the program
the "ls" command to execute:
-------------------------------
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from d:\git\tubo\src\.libs\example.exe...done.
(gdb) run
Starting program: d:\git\tubo\src\.libs\example.exe
[New Thread 6504.0x17f8]
command (exit to end):ls
found: E:\MinGW\msys\1.0\bin\ls.exe
exec> Main process id = 0x1968
posting semaphore 1...
posted semaphore 1 !
Child process id= 0x1080
Controller process id= 0x1980
Tubo_id() = 0x2
wait is done for 0x1080
0x1968: Tubo_exec thread processing: Makefile
0x1968: Tubo_exec thread processing: Makefile.am
0x1968: Tubo_exec thread processing: Makefile.in
0x1968: Tubo_exec thread processing: example-example.o
0x1968: Tubo_exec thread processing: example-tubo.o
0x1968: Tubo_exec thread processing: example-tubo_exec.o
0x1968: Tubo_exec thread processing: example.c
0x1968: Tubo_exec thread processing: example.exe
0x1968: Tubo_exec thread processing: libtubo.dll
0x1968: Tubo_exec thread processing: libtubo.la
0x1968: Tubo_exec thread processing: libtubo_la-tubo.lo
0x1968: Tubo_exec thread processing: libtubo_la-tubo.o
0x1968: Tubo_exec thread processing: libtubo_la-tubo_exec.lo
0x1968: Tubo_exec thread processing: libtubo_la-tubo_exec.o
0x1968: Tubo_exec thread processing: tubo.c
0x1968: Tubo_exec thread processing: tubo.h
0x1968: Tubo_exec thread processing: tubo_exec.c
0x1968: Tubo_exec thread processing: tubo_exec.c~
0x1968: Tubo_exec thread processing: tubo_exec.i
0x1968: Tubo_exec thread processing: tubo_exec.i~
0x1968: Tubo_exec thread processing: tubo_main.c
0x1968: Tubo_exec thread processing: tubo_static.i
0x1968: Tubo_exec thread processing: tuboexec-tubo.o
0x1968: Tubo_exec thread processing: tuboexec-tubo_main.o
0x1968: Tubo_exec thread processing: tuboexec.exe
0x1968: Tubo_exec thread processing:
[New Thread 6504.0x1798]
[New Thread 6504.0x1be4]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 6504.0x1798]
0x62487810 in pthread_mutex_lock () from e:\MinGW\bin\pthreadGC2.dll
---------------------------

That's the extent of information I could get from gdb, but after fiddling
around, I find that a sem_ command (probably sem_wait) is causing the crash
with the detected pthread_mutex_lock() call. So me figures that pthread
semaphores are just constructed with pthread_conditions. So instead I use
mutex/condition to hack up a control equivalent to the required semaphore
and everything works just fine.

That leads me to believe that there may be some race condition with
semaphores in pthreadGC2, where the associated mutex of the underlying
control structure gets freed before its time is really up.

This is what I was talking about. All this was done with plain MingW. I
have yet to build dll's with Mingw-64, but I surmise the issue will be the
same.

I'll be glad to provide any more information if needed.

HTH







-- 
------------------------------------------------------------------------------------
Dr. Edscott Wilson Garcia
Applied Mathematics and Computing
Mexican Petroleum Institute
------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to