• #### Re: Is there a way to wait for WRITE?

From Thomas Koenig@21:1/5 to James Van Buskirk on Sun Nov 13 08:55:51 2022
James Van Buskirk <not_valid@comcast.net> schrieb:
OK, I made some progress in my hobby project and now it
displays a graph of its results. I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

You can also use the pngtopng command from netpbm, which
is a bit more lightweight than gimp :-)

Then I wrote a *.bat file that permits me to run a bunch
of scenarios. Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes,

Do you do different threads in a main program? If
so, how? OpenMP? Coarrays? pthreads? Windows

Or did you just mean program?

so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

This is very hard to answer without knowing exactly what
you did, what system (I presume Windows), and what
thread model and what compiler you used.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to All on Sun Nov 13 01:46:36 2022
OK, I made some progress in my hobby project and now it
displays a graph of its results. I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

Then I wrote a *.bat file that permits me to run a bunch
of scenarios. Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to Thomas Koenig on Sun Nov 13 03:02:54 2022
"Thomas Koenig" wrote in message news:tkqben$38a5n$1@newsreader4.netcologne.de...

James Van Buskirk <not_valid@comcast.net> schrieb:
OK, I made some progress in my hobby project and now it
displays a graph of its results. I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

You can also use the pngtopng command from netpbm, which
is a bit more lightweight than gimp :-)

Well, I installed gimp for a previous project and its licensing
arrangements seemed satisfactory. It's a bitch to use it in
batch mode, though. What would have been really cool
would have been a printer driver that had the option to
print to file with *.png being one of the accessible formats.
Then I could have rendered to the file like I have rendered
to printer previously. However, Windows doesn't come with
such goodies: Microsoft XPS Document Writer seems to be
able to embed a PNG in a *.oxps file, but I couldn't figure
out how to extract it from there. There are drivers out
there on the web that can print to *.png, but using them
would mean the my program wouldn't be self-contained.

Then I wrote a *.bat file that permits me to run a bunch
of scenarios. Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes,

Do you do different threads in a main program? If
so, how? OpenMP? Coarrays? pthreads? Windows

Or did you just mean program?

No, Windows threads with _beginthreadex() and the
whole 9 yards. I tried putting a WaitForSingleObject
call before program termination, but it had no effect.
Seemingly the thread (and my *.ppm file) were already
long gone by that time.

so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

This is very hard to answer without knowing exactly what
you did, what system (I presume Windows), and what
thread model and what compiler you used.

D:\gfortran\james>gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw64/bin/../libexec/gcc/x86_64-w64-ming
w32/12.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with:
../../../src/gcc-12.2.0/configure --host=x86_64-w64-mingw32 --b uild=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sys
root=/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64 --enable-host-shared
--disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time =yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto
--e
nable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-
version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-lib
stdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disabl
e-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system
-zlib --with-gmp=/c/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpf
r=/c/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/buildroot/p
rerequisites/x86_64-w64-mingw32-static --with-isl=/c/buildroot/prerequisites/x86
_64-w64-mingw32-static --with-pkgversion='x86_64-win32-seh-rev1, Built by MinGW-
W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O
2 -pipe -fno-ident -I/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64/opt/
include -I/c/buildroot/prerequisites/x86_64-zlib-static/include -I/c/buildroot/p
rerequisites/x86_64-w64-mingw32-static/include'
CXXFLAGS='-O2 -pipe -fno-ident - I/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64/opt/include -I/c/buildro
ot/prerequisites/x86_64-zlib-static/include -I/c/buildroot/prerequisites/x86_64-
w64-mingw32-static/include'
CPPFLAGS=' -I/c/buildroot/x86_64-1220-win32-seh-rt_v 10-rev1/mingw64/opt/include -I/c/buildroot/prerequisites/x86_64-zlib-static/incl
ude -I/c/buildroot/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pi
pe -fno-ident -L/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64/opt/lib
-
L/c/buildroot/prerequisites/x86_64-zlib-static/lib -L/c/buildroot/prerequisites/
x86_64-w64-mingw32-static/lib ' LD_FOR_TARGET=/c/buildroot/x86_64-1220-win32-seh -rt_v10-rev1/mingw64/bin/ld.exe --with-boot-ldflags=' -Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc'
Supported LTO compression algorithms: zlib
gcc version 12.2.0 (x86_64-win32-seh-rev1, Built by MinGW-W64 project)

As you can see, the compiler is using win32 threads rather than posix. I
difficulties early on so I downloaded this compiler although I am not sure
if
it is necessary to use the win32 threads gfortran compiler if you are making threads via the Win32 API.

The program is kinda long: win.f90=33 kB, gl.f90=41 kB, xygraph.f90 = 58 kB
and even my calculational engine is 47 kB. It definitely needs Windows to
work and the ifort-compiled version just hangs without any output.
Thus, it wouldn't do much good to post the code because nobody would
have the time, energy, and ability to investigate it.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Spiros Bousbouras@21:1/5 to Thomas Koenig on Sun Nov 13 12:10:12 2022
On Sun, 13 Nov 2022 11:24:21 -0000 (UTC)
Thomas Koenig <tkoenig@netcologne.de> wrote:
James Van Buskirk <not_valid@comcast.net> schrieb:
"Thomas Koenig" wrote in message news:tkqben$38a5n$1@newsreader4.netcologne.de...

James Van Buskirk <not_valid@comcast.net> schrieb:
After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

You can also use the pngtopng command from netpbm, which
is a bit more lightweight than gimp :-)

Well, I installed gimp for a previous project and its licensing arrangements seemed satisfactory. It's a bitch to use it in
batch mode, though.

That is what netpbm is for.

You could just do

CALL EXECUTE_COMMAND_LINE ("pngtopng yourfile.ppm > yourfile.png")

from your Fortran program, this should work. It might open a
cmd window, though.

Is there a pngtopng programme ? Do you mean pnmtopng perhaps ?

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Thomas Koenig@21:1/5 to James Van Buskirk on Sun Nov 13 11:24:21 2022
James Van Buskirk <not_valid@comcast.net> schrieb:
"Thomas Koenig" wrote in message news:tkqben$38a5n$1@newsreader4.netcologne.de...

James Van Buskirk <not_valid@comcast.net> schrieb:
OK, I made some progress in my hobby project and now it
displays a graph of its results. I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

You can also use the pngtopng command from netpbm, which
is a bit more lightweight than gimp :-)

Well, I installed gimp for a previous project and its licensing
arrangements seemed satisfactory. It's a bitch to use it in
batch mode, though.

That is what netpbm is for.

You could just do

CALL EXECUTE_COMMAND_LINE ("pngtopng yourfile.ppm > yourfile.png")

from your Fortran program, this should work. It might open a
cmd window, though.

What would have been really cool
would have been a printer driver that had the option to
print to file with *.png being one of the accessible formats.
Then I could have rendered to the file like I have rendered
to printer previously. However, Windows doesn't come with
such goodies: Microsoft XPS Document Writer seems to be
able to embed a PNG in a *.oxps file, but I couldn't figure
out how to extract it from there. There are drivers out
there on the web that can print to *.png, but using them
would mean the my program wouldn't be self-contained.

Then I wrote a *.bat file that permits me to run a bunch
of scenarios. Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes,

Do you do different threads in a main program? If
so, how? OpenMP? Coarrays? pthreads? Windows

Or did you just mean program?

No, Windows threads with _beginthreadex() and the
whole 9 yards.

OK, then I'm afraid I cannot really help you a lot. Just a couple
of things:

The gfortran runtime knows nothing about Windows threads. You have
to make sure that there is no race condition etc. libgfortran
locking is for pthreads only (which also works for gomp).

If you are using threads, you will probably need -frecursive
to make sure that all variables are on the stack.

I tried putting a WaitForSingleObject
call before program termination, but it had no effect.
Seemingly the thread (and my *.ppm file) were already
long gone by that time.

If your thread exited (how did you do that?) it might
have cleaned up after itself in some way, and left
the runtime in an inconsistent state.

The least you probably have to do is to make sure that any I/O
library calls are only executed on a single thread, by putting
the Windows equivalent of "omp critical" around it.

so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

This is very hard to answer without knowing exactly what
you did, what system (I presume Windows), and what
thread model and what compiler you used.

D:\gfortran\james>gfortran -v

[...]

As you can see, the compiler is using win32 threads rather than posix. I
difficulties early on so I downloaded this compiler although I am not sure
if
it is necessary to use the win32 threads gfortran compiler if you are making threads via the Win32 API.

I have no idea about that, my systems programming fu is limited
to UNIX.

The program is kinda long: win.f90=33 kB, gl.f90=41 kB, xygraph.f90 = 58 kB and even my calculational engine is 47 kB. It definitely needs Windows to work and the ifort-compiled version just hangs without any output.
Thus, it wouldn't do much good to post the code because nobody would
have the time, energy, and ability to investigate it.

If it's a hobby project, maybe you want to completely rewrite it in
gtk-fortran :-)

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Thomas Koenig@21:1/5 to Spiros Bousbouras on Sun Nov 13 12:50:47 2022
Spiros Bousbouras <spibou@gmail.com> schrieb:
On Sun, 13 Nov 2022 11:24:21 -0000 (UTC)
Thomas Koenig <tkoenig@netcologne.de> wrote:
James Van Buskirk <not_valid@comcast.net> schrieb:
"Thomas Koenig" wrote in message
news:tkqben$38a5n$1@newsreader4.netcologne.de...

James Van Buskirk <not_valid@comcast.net> schrieb:
After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

You can also use the pngtopng command from netpbm, which
is a bit more lightweight than gimp :-)

Well, I installed gimp for a previous project and its licensing
arrangements seemed satisfactory. It's a bitch to use it in
batch mode, though.

That is what netpbm is for.

You could just do

CALL EXECUTE_COMMAND_LINE ("pngtopng yourfile.ppm > yourfile.png")

from your Fortran program, this should work. It might open a
cmd window, though.

Is there a pngtopng programme ? Do you mean pnmtopng perhaps ?

Yes, of course.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to Thomas Koenig on Sun Nov 13 05:39:23 2022
"Thomas Koenig" wrote in message news:tkqk55$38e2i$1@newsreader4.netcologne.de...

If you are using threads, you will probably need -frecursive
to make sure that all variables are on the stack.

No, I explicitly declare all my procedures as recursive.

If your thread exited (how did you do that?) it might
have cleaned up after itself in some way, and left
the runtime in an inconsistent state.

I think that's inconsistent with the symptoms in that
if the calling program is stalled waiting for input the
data is not lost. Maybe I will put a call Sleep(1000) or
so as a workaround but I have other stuff I have to mess
with in the immediate future.

The least you probably have to do is to make sure that any I/O
library calls are only executed on a single thread, by putting
the Windows equivalent of "omp critical" around it.

In earlier testing this was no problem, just somewhat
difficult to interpret output. When the failure occurs only
the failing thread is performing I/O.

If it's a hobby project, maybe you want to completely rewrite it in gtk-fortran :-)

There are problems with that project I have mentioned
long ago, and it's not really a Windows thing. Can you
create an OpenGK render context in gtk-fortran, for
example? Linux has this issue with graphics that there
are different foundations, like X11 is what non-Linux
speakers would have thought was the foundation in
Linux, but it's built on top of another package whose
name I can't recall any more. Everyone on Linux seems
to use GLUT, which is a bad sign.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Thomas Koenig@21:1/5 to James Van Buskirk on Sun Nov 13 14:18:52 2022
James Van Buskirk <not_valid@comcast.net> schrieb:
"Thomas Koenig" wrote in message news:tkqk55$38e2i$1@newsreader4.netcologne.de...

If you are using threads, you will probably need -frecursive
to make sure that all variables are on the stack.

No, I explicitly declare all my procedures as recursive.

If your thread exited (how did you do that?) it might
have cleaned up after itself in some way, and left
the runtime in an inconsistent state.

I think that's inconsistent with the symptoms in that
if the calling program is stalled waiting for input the
data is not lost.

It might still be in an inconsistent state.

libgfortran is simply not built for several threads
doing stuff without it knowing about it. It does locking,
but only for pthreads.

so as a workaround but I have other stuff I have to mess
with in the immediate future.

:-)

The least you probably have to do is to make sure that any I/O
library calls are only executed on a single thread, by putting
the Windows equivalent of "omp critical" around it.

In earlier testing this was no problem, just somewhat
difficult to interpret output. When the failure occurs only
the failing thread is performing I/O.

Accessing

If it's a hobby project, maybe you want to completely rewrite it in
gtk-fortran :-)

There are problems with that project I have mentioned
long ago, and it's not really a Windows thing. Can you
create an OpenGK render context in gtk-fortran, for
example?

I assume you mean OpenGL?

Does https://docs.gtk.org/gtk4/class.GLArea.html qualify?
(I don't know a lot about OpenGL, so I am just guessing).

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Jones@21:1/5 to James Van Buskirk on Sun Nov 13 15:46:34 2022
James Van Buskirk wrote:

OK, I made some progress in my hobby project and now it
displays a graph of its results. I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

Then I wrote a *.bat file that permits me to run a bunch
of scenarios. Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

Have you tried a WAIT or SLEEP function to provide the required delay
of a small faction of a second, as judged by experience?

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From John@21:1/5 to All on Sun Nov 13 07:28:00 2022
No direct help for the issues you describe that someone has not mentioned already, but if you are just writing Poskanzer pixelmaps from a batch problem I would mention a few other possibilities

It sounds like you using a lot of MSWIndows-specific components, threaded, and so on. On the other hand you seem to be creating a P6 file at a low level. If you have an internal array representing a pixel map you might consider writing GIF; I have used

https://fortranwiki.org/fortran/show/writegif

which is in Fortran and so can be very portable with no dependencies.

I am a fan of Netpbm+ for batch use, and have generated low-level P6 graphics quite a bit (even have a hopefully portable module just for that); see https://github.com/urbanjost/M_pixel and https://github.com/urbanjost/M_draw for example. That
approach can work very well for simple projects where longevity and portability matter; particularly with batch-generated graphics (I have programs that have been on dozens of OSes and are decades old still running taking that approach) but it is not
the way to go for high-level event-driven threaded codes or for most high-level graphics. So not quite sure such a low-level approach is of any use; but thought I would mention it as you are mentioning P6 files (again, have used them for years with
great success).

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to seem to incorporate the capability on Sun Nov 13 13:26:32 2022
"John" wrote in message news:7f7fcb28-c232-468e-9432-04801f51cbf6n@googlegroups.com...

No direct help for the issues you describe that someone has
not mentioned already, but if you are just writing Poskanzer
pixelmaps from a batch problem I would mention a few other
possibilities

It sounds like you using a lot of MSWIndows-specific
components, threaded, and so on. On the other hand you
seem to be creating a P6 file at a low level. If you have an
internal array representing a pixel map you might consider
writing GIF; I have used

https://fortranwiki.org/fortran/show/writegif

It's too bad it's writing GIFs rather than PNGs. It doesn't
seem to incorporate the capability to write animated GIFs
and GIFs have limitations.

which is in Fortran and so can be very portable with
no dependencies.

I am a fan of Netpbm+ for batch use, and have generated
low-level P6 graphics quite a bit (even have a hopefully
portable module just for that); see
https://github.com/urbanjost/M_pixel and
https://github.com/urbanjost/M_draw
for example. That approach can work very well for
simple projects where longevity and portability matter;
particularly with batch-generated graphics (I have programs
that have been on dozens of OSes and are decades old still
running taking that approach) but it is not the way to go
for high-level event-driven threaded codes or for most
high-level graphics. So not quite sure such a low-level
approach is of any use; but thought I would mention it
as you are mentioning P6 files (again, have used them for
years with great success).

Yeah, P6 *.ppm is the graphics file format for the rest of us:
you can just look at the specification and generate graphics
files immediately. It's too bad that more software can't

I see that M_pixel does do animated GIFs. It's a pity that
there isn't an obvious link on the page that tells you how
to download the package. I can't understand why GitHub
doesn't provide that.

I would just do raw raster graphics if it weren't for the fonts.
You know, like a Fortran mathjax to raster library :)

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Gary Scott@21:1/5 to Gary Scott on Sun Nov 13 14:22:37 2022
On 11/13/2022 2:18 PM, Gary Scott wrote:
On 11/13/2022 2:46 AM, James Van Buskirk wrote:
OK, I made some progress in my hobby project and now it
displays a graph of its results.  I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

Then I wrote a *.bat file that permits me to run a bunch
of scenarios.  Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy.  How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

I sometimes use a shared memory buffer to communication with separate processes or threads.  Example of the win32 api for this is here:

https://www.fortranlib.com/ShareBufferWin32.f90

You can make it virtually any size you want.  I sometimes use various
flags (wait, kill, etc.) to synchronize with hardware or software.

Here's the example at the bottom of the linked file:

!
! Example Main Program 1
!
! integer :: iretcode, bufptr, buffer(1024)
!
! pointer (bufptr,buffer)
!
!
! call CreateShareBuffer('TestBuf',4096,bufptr,iretcode)
!
!
! ...code using BUFFER goes here.
!
! ...when finished...
!
!
! call DeleteShareBuffer(bufptr,iretcode)
!
! end
!
!
!
! Example Main Program 2 (3, 4, etc.)
!
! integer :: iretcode, bufptr, buffer(1024)
!
! pointer (bufptr,buffer)
!
!
! call OpenShareBuffer('TestBuf',bufptr,iretcode)
!
!
! ...code using BUFFER goes here.
!
! ...when finished...
!
!
! call CloseShareBuffer(bufptr,iretcode)
!
! end

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Gary Scott@21:1/5 to James Van Buskirk on Sun Nov 13 14:18:59 2022
On 11/13/2022 2:46 AM, James Van Buskirk wrote:
OK, I made some progress in my hobby project and now it
displays a graph of its results.  I put a READ(*,'(a)') statement
at the end so my graphs wouldn't go away when the
program terminates.

After considerable effort I found out how to write a *.ppm
file and how to get gimp.exe to convert all of my *.ppm
files (which most software can't read) to *.png.

Then I wrote a *.bat file that permits me to run a bunch
of scenarios.  Since I didn't want to have to change focus
to the CMD.exe window and hit <ENTER> for every run
of the program, I had it detect when it was running in batch
mode and skip the READ(*,'(a)') statement because the
graphs would be available in *.png form anyway.

However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy.  How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

I sometimes use a shared memory buffer to communication with separate
processes or threads. Example of the win32 api for this is here:

https://www.fortranlib.com/ShareBufferWin32.f90

You can make it virtually any size you want. I sometimes use various
flags (wait, kill, etc.) to synchronize with hardware or software.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to David Jones on Sun Nov 13 13:35:04 2022
"David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...

James Van Buskirk wrote:
However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

Have you tried a WAIT or SLEEP function to provide the required delay
of a small faction of a second, as judged by experience?

Yeah, that's the first thing I plan to try when I get the
resources (time and energy) to struggle with this problem
again. It might need to be a couple of seconds, but the
overall program takes a couple of minutes to run at
parameters near to what currently makes it crash by
flying too close to the sun.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to Gary Scott on Sun Nov 13 13:42:10 2022
"Gary Scott" wrote in message news:tkrjfj$1h7po$1@dont-email.me...

I sometimes use a shared memory buffer to communication with separate processes or threads. Example of the win32 api for this is here:

https://www.fortranlib.com/ShareBufferWin32.f90

You can make it virtually any size you want. I sometimes use various
flags (wait, kill, etc.) to synchronize with hardware or software.

I seems that your solution would be to create a shared buffer that
the dying thread would allocate and fill with data in its last gasp
and then the main program would write the data to file.

I think that might work but I was hoping for a solution that
preserved the current division of labor.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From David Jones@21:1/5 to James Van Buskirk on Sun Nov 13 22:45:04 2022
James Van Buskirk wrote:

"David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...
James Van Buskirk wrote:
However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

Have you tried a WAIT or SLEEP function to provide the required
delay of a small faction of a second, as judged by experience?

Yeah, that's the first thing I plan to try when I get the
resources (time and energy) to struggle with this problem
again. It might need to be a couple of seconds, but the
overall program takes a couple of minutes to run at
parameters near to what currently makes it crash by
flying too close to the sun.

A possible (flexible on time?) strategy might be to interactively try
to open-for-exclusive-read the file once you have closed it, with a
WAIT or SLEEP between tries. THIs mighrt ensure the system thinks the
file properly exists before you close the program.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Gary Scott@21:1/5 to James Van Buskirk on Sun Nov 13 18:12:32 2022
On 11/13/2022 2:42 PM, James Van Buskirk wrote:
"Gary Scott"  wrote in message news:tkrjfj$1h7po$1@dont-email.me...
I sometimes use a shared memory buffer to communication with separate
processes or threads.  Example of the win32 api for this is here:

https://www.fortranlib.com/ShareBufferWin32.f90

You can make it virtually any size you want.  I sometimes use various
flags (wait, kill, etc.) to synchronize with hardware or software.

I seems that your solution would be to create a shared buffer that
the dying thread would allocate and fill with data in its last gasp
and then the main program would write the data to file.

I think that might work but I was hoping for a solution that
preserved the current division of labor.

I don't think the division of labor would need to change, just use one
or two shared variables (in the swap file) to communicate between the
threads and synchronize as needed. Maybe when the thread is done, it
sets a shared flag when it completes or it waits until the main sets a
flag to allow the thread to continue/process. Better than an arbitrary wait/delay.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From gah4@21:1/5 to James Van Buskirk on Sun Nov 13 15:47:36 2022
On Sunday, November 13, 2022 at 2:04:12 AM UTC-8, James Van Buskirk wrote:

(snip)

No, Windows threads with _beginthreadex() and the
whole 9 yards. I tried putting a WaitForSingleObject
call before program termination, but it had no effect.
Seemingly the thread (and my *.ppm file) were already
long gone by that time.

Sounds like a Windows bug.

Any asynchronous operation should have the ability to WAIT for
it to finish.

Fortran asynchronous I/O has a WAIT statement such that you can
wait for the operation to be done. For READ, you can't look at the data
until after the WAIT. For WRITE, you can't reuse the output buffer until
after WAIT.

For OS/360, I/O is naturally asynchronous, each operation has an ECB
(Event Control Block) which is used with a WAIT macro. And as above,
you can't use the read data, or reuse the output buffer, until the WAIT
has finished.

So, for example, you do double buffer I/O by starting two READ operations,
and then WAITing for the first. When it is done, you use the data supplied. (Or copy it away somewhere.) Then start the third and WAIT for the second.

And subtasks also have an ECB and you can WAIT for them.

IBM versions of PL/I have EVENT variables, which most likely have
the ECB inside them, and a WAIT statement. That is used for both
asynchronous I/O and subtasks.

Asynchronous operations are pretty fundamental in Unix, too.

It might be, though, that they were added on later to Windows, and not
so well integrated as they could have been.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Gary Scott@21:1/5 to Gary Scott on Sun Nov 13 20:10:18 2022
On 11/13/2022 7:59 PM, Gary Scott wrote:
On 11/13/2022 6:12 PM, Gary Scott wrote:
On 11/13/2022 2:42 PM, James Van Buskirk wrote:
"Gary Scott"  wrote in message news:tkrjfj$1h7po$1@dont-email.me...
I sometimes use a shared memory buffer to communication with
separate processes or threads.  Example of the win32 api for this is
here:

https://www.fortranlib.com/ShareBufferWin32.f90

You can make it virtually any size you want.  I sometimes use
various flags (wait, kill, etc.) to synchronize with hardware or
software.

I seems that your solution would be to create a shared buffer that
the dying thread would allocate and fill with data in its last gasp
and then the main program would write the data to file.

I think that might work but I was hoping for a solution that
preserved the current division of labor.

I don't think the division of labor would need to change, just use one
or two shared variables (in the swap file) to communicate between the
threads and synchronize as needed.  Maybe when the thread is done, it
sets a shared flag when it completes or it waits until the main sets a
flag to allow the thread to continue/process.  Better than an
arbitrary wait/delay.
Another possibility that I sometimes use is shared file access.  On
windows, I'll reserve usually a header at the beginning of the file
(usually direct access, but it works with stream and other forms as
well).  The header may contain a flag to indicate the availability state
for reading or writing by other processes (or threads).  In my
application, I also implemented record locks in each record (and
timestamps at beginning and end of record and check sums, etc.).  It
seems completely reliable.  I've never had a data corruption in decades
and billions of read/writes, knock on wood :)

SHARE
'DENYRW'
'DENYWR'
'DENYRD'
'DENYNONE'
File locking
'DENYWR'
Note: The default differs under certain conditions (see SHARE Specifier). Other notes:
'DENYWR': on Linux* and macOS systems, the default depends only on the
FORM setting.
'DENYRD': applies to Windows.
SHARED
No value
File sharing allowed
Linux* and macOS: SHARED
Windows: Not shared
Of course you have to be careful with some forms as they will truncate
the file if you try to write to a "header". You'll have to open the
file with a form that allows you to "tweak" the contents in place.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Gary Scott@21:1/5 to Gary Scott on Sun Nov 13 19:59:01 2022
On 11/13/2022 6:12 PM, Gary Scott wrote:
On 11/13/2022 2:42 PM, James Van Buskirk wrote:
"Gary Scott"  wrote in message news:tkrjfj$1h7po$1@dont-email.me...
I sometimes use a shared memory buffer to communication with separate
processes or threads.  Example of the win32 api for this is here:

https://www.fortranlib.com/ShareBufferWin32.f90

You can make it virtually any size you want.  I sometimes use various
flags (wait, kill, etc.) to synchronize with hardware or software.

I seems that your solution would be to create a shared buffer that
the dying thread would allocate and fill with data in its last gasp
and then the main program would write the data to file.

I think that might work but I was hoping for a solution that
preserved the current division of labor.

I don't think the division of labor would need to change, just use one
or two shared variables (in the swap file) to communicate between the
threads and synchronize as needed.  Maybe when the thread is done, it
sets a shared flag when it completes or it waits until the main sets a
flag to allow the thread to continue/process.  Better than an arbitrary wait/delay.
Another possibility that I sometimes use is shared file access. On
windows, I'll reserve usually a header at the beginning of the file
(usually direct access, but it works with stream and other forms as
well). The header may contain a flag to indicate the availability state
for reading or writing by other processes (or threads). In my
application, I also implemented record locks in each record (and
timestamps at beginning and end of record and check sums, etc.). It
seems completely reliable. I've never had a data corruption in decades
and billions of read/writes, knock on wood :)

SHARE
'DENYRW'
'DENYWR'
'DENYRD'
'DENYNONE'
File locking
'DENYWR'
Note: The default differs under certain conditions (see SHARE Specifier).
Other notes:
'DENYWR': on Linux* and macOS systems, the default depends only on the
FORM setting.
'DENYRD': applies to Windows.
SHARED
No value
File sharing allowed
Linux* and macOS: SHARED
Windows: Not shared

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to All on Sun Nov 13 19:46:55 2022
"gah4" wrote in message news:10f6e9a0-658b-41db-b500-cf1474588555n@googlegroups.com...

Fortran asynchronous I/O has a WAIT statement such that you can
wait for the operation to be done. For READ, you can't look at the data until after the WAIT. For WRITE, you can't reuse the output buffer until after WAIT.

I didn't realize that the committee had sneaked asynchronous I/O in
there. Unfortunately, as Thomas Koenig said, it doesn't work in
gfortran on Windows.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to David Jones on Sun Nov 13 20:03:45 2022
"David Jones" wrote in message news:tkrs1g$1q1t$1@gioia.aioe.org...

A possible (flexible on time?) strategy might be to interactively try
to open-for-exclusive-read the file once you have closed it, with a
WAIT or SLEEP between tries. THIs mighrt ensure the system thinks the
file properly exists before you close the program.

call Sleep(1000)

seemed to work consistently and I don't want to spend too much
time on this problem. What happens if you can open for exclusive
read and then the writing process decides that now is the time to
open the file for writing?

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From gah4@21:1/5 to James Van Buskirk on Sun Nov 13 21:40:27 2022
On Sunday, November 13, 2022 at 7:04:47 PM UTC-8, James Van Buskirk wrote:

(snip)

seemed to work consistently and I don't want to spend too much
time on this problem. What happens if you can open for exclusive
read and then the writing process decides that now is the time to
open the file for writing?

One of the fun things about Unix is that it mostly doesn't even try to
do file locking. Programs can do any (more than one) thing to a file
at the same time, sometimes with strange results.

Windows tries to do file locking, more often than not, locking you
out from something you should be able to do.

The computer that I write this on is a MacBook Air with some disks
NFS mounted off servers on the network. I had to put nolocks on
the NFS mount command, otherwise it keeps locking them when
it isn't supposed to.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Thomas Koenig@21:1/5 to James Van Buskirk on Mon Nov 14 06:40:24 2022
James Van Buskirk <not_valid@comcast.net> schrieb:
"gah4" wrote in message news:10f6e9a0-658b-41db-b500-cf1474588555n@googlegroups.com...

Fortran asynchronous I/O has a WAIT statement such that you can
wait for the operation to be done. For READ, you can't look at the data
until after the WAIT. For WRITE, you can't reuse the output buffer until
after WAIT.

I didn't realize that the committee had sneaked asynchronous I/O in
there. Unfortunately, as Thomas Koenig said, it doesn't work in
gfortran on Windows.

The committee left in a loophole so that it was OK for asynchronous
I/O to be done synchronously, which how gfortran implemented it
until 2018.

The implementation is built on pthreads, though.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From John@21:1/5 to James Van Buskirk on Mon Nov 14 06:43:27 2022
On Sunday, November 13, 2022 at 3:36:07 PM UTC-5, James Van Buskirk wrote:
"David Jones" wrote in message news:tkr3gq$nkk$1...@gioia.aioe.org...
James Van Buskirk wrote:
However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

Have you tried a WAIT or SLEEP function to provide the required delay
of a small faction of a second, as judged by experience?
Yeah, that's the first thing I plan to try when I get the
resources (time and energy) to struggle with this problem
again. It might need to be a couple of seconds, but the
overall program takes a couple of minutes to run at
parameters near to what currently makes it crash by
flying too close to the sun.

When you are looking at github packages, you can use a git command (or git GUI) and copy an entire repo to your platform, as in

git clone https://github.com/urbanjost/M_draw.git

or if you are an fpm(1) user you can just list the repository as a dependency; if the maintainer made
a release file that should be a single file in zip or tar format that contains the entire repository;

but if not a git user and there is no release files for specific versions, a regular download is (oddly)
under the [CODE] button on the right (not the [CODE] button on the upper left). It gives you an option
there to download the project as a ZIP file that is built on the file.

RE: fonts

Yeah, currently M_pixel just has a couple of built-in Hershey vector fonts; M_draw has a much better Hershey font support and very basic hardware font support on devices that have them; for my uses that works very well as it is highly portable; but
not very attractive.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From Thomas Koenig@21:1/5 to James Van Buskirk on Mon Nov 14 17:55:10 2022
James Van Buskirk <not_valid@comcast.net> schrieb:
"David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...

James Van Buskirk wrote:
However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

Have you tried a WAIT or SLEEP function to provide the required delay
of a small faction of a second, as judged by experience?

Yeah, that's the first thing I plan to try when I get the
resources (time and energy) to struggle with this problem
again.

Another possibility: Have the writing thread open the file under
another name, and upon completion, rename it to the final name
(using the non-standard RENAME function or subroutine).

The other thread can then INQUIRE for the existence of
the file in a loop, possibly with a SLEEP thrown in.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)
• From James Van Buskirk@21:1/5 to All on Mon Nov 14 19:01:50 2022
"Thomas Koenig" wrote in message news:tktvdu$3amf6$1@newsreader4.netcologne.de...

James Van Buskirk <not_valid@comcast.net> schrieb:
"David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...

James Van Buskirk wrote:
However, this caused a problem because the last and of
course most important *.ppm doesn't complete writing
before its thread closes, so I don't get that *.ppm file.
I tried putting a FLUSH(iunit) statement before the
CLOSE(iunit) statement, but still no joy. How am I
supposed to tell the thread to wait for the *.ppm file
to get properly written and saved before returning?

Have you tried a WAIT or SLEEP function to provide the required delay
of a small faction of a second, as judged by experience?

Yeah, that's the first thing I plan to try when I get the
resources (time and energy) to struggle with this problem
again.

Another possibility: Have the writing thread open the file under
another name, and upon completion, rename it to the final name
(using the non-standard RENAME function or subroutine).

The other thread can then INQUIRE for the existence of
the file in a loop, possibly with a SLEEP thrown in.

Given that the 'right' solution is asynchronous I/O and that
I have a workaround with Sleep, I have put this issue on the
backburner for now.

At this point the graphics isn't too bad if you consider the
lack of Greek characters and subscripts in the axis labels
and title, so I am back to the calculational component.
I am trying to determine whether I need arbitrary
precision and how much good it will do me. The present
limit seems to be due to an ill-conditioned Jacobian in a
context where another approach may be able to make
forward progress.

--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)