Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Visual FORTRAN Console Apps sharing a Common Block

0 views
Skip to first unread message

itooth

unread,
Jul 23, 2003, 6:28:09 PM7/23/03
to
I am using Compaq Visual FORTRAN with WinXP.
We have several old FORTRAN77 programs we are porting from a DEC Alpha
Ultrix platform to WinXP. The programs have one large FORTRAN common block
named datapool. Using VF I have built them as VF console applications. How
can I get the console applications (processes) to share the common block?
(Interprocess communication).

I read through the newsgroup and have searched the web and even read the
Compaq VF user's guide:-) but I have not found an answer. Can someone
please explain the various ways to share the common block within VF?

Thank you.


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----

Jugoslav Dujic

unread,
Jul 24, 2003, 6:18:03 AM7/24/03
to
itooth wrote:
| I am using Compaq Visual FORTRAN with WinXP.
| We have several old FORTRAN77 programs we are porting from a DEC Alpha
| Ultrix platform to WinXP. The programs have one large FORTRAN common block
| named datapool. Using VF I have built them as VF console applications. How
| can I get the console applications (processes) to share the common block?
| (Interprocess communication).
|
| I read through the newsgroup and have searched the web and even read the
| Compaq VF user's guide:-) but I have not found an answer. Can someone
| please explain the various ways to share the common block within VF?

Well, that's not so easy. AFAIK Windows does not allow common block
sharing among different processes. One possibility is to put the shared
commons into a dll, DLLEXPORT them from there, and DLLIMPORT them from
exes. However, you will have to find a way (I don't know) how to specify
#pragma data_seg(".shared") in CVF in order to specify that the data
segment in question is shared amongst all instances of the dll.
See Q125677 in MSDN and related links
(http://support.microsoft.com/default.aspx?scid=kb;EN-US;q125677)

An alternative with potentially less gotchas (but requires more
changes in the source) is to use file mappings. There's a convenient
wrapper ShareBufferWin32.f90 at http://www.fortranlib.com/freesoft.htm.
However, the gotcha here is that you can't say "here's my common block
-- share it", but only, "gimme a shared memory of size n". In other
words, you have to find a way to map the common to given memory block.
Since commons cannot be instantiated at will, you will have to:

- convert the common block to a derived TYPE, e.g. T_DATAPOOL
- declare a global pointer, say T, of type T_DATAPOOL:
type(T_DATAPOOL), pointer: T. Put it in a module, say
M_DATAPOOL.
- now, you can map T to an address returned by CreateShareBuffer.
To do it, you have to (ab)use CVF feature that a scalar pointer
is just an address (void* or LPVOID). So, you have to "lie" to the
compiler that bufferAddress argument should be a pointer to a T_DATAPOOL,
not an integer. Put the following interfaces into a module, say
M_SHARED:

interface
subroutine CreateShareBuffer(bufferName,numBytes,bufferAddress,iRetcode)
USE M_DATAPOOL
character(*), intent(in) :: bufferName
integer, intent(in) :: numBytes
integer, intent(out) :: iRetcode
TYPE(T_DATAPOOL), POINTER:: bufferAddress
end subroutine
end interface

Do so for every routine containing bufferAddress from ShareBufferWin32.f90.
- Now, call CreateShareBuffer in the "first" exe. On startup of every exe, call
OpenShareBuffer like:
USE M_DATAPOOL
USE M_SHARED
call OpenShareBuffer("MyShareBuffer", T, iErr)

The greatest pain, I'm affraid, is that you'll have to replace all
occurrences of every variable X from the datapool with T%X.

--
Jugoslav
___________
www.geocities.com/jdujic


Gary L. Scott

unread,
Jul 24, 2003, 7:41:52 AM7/24/03
to

Don't forget to closesharebuffer at conclusion of each "slave" exe.
This would normally be done in the "master" exe. So if possible, the
"master" exe should be responsible for terminating the other exes in an
orderly manner. I probably should investigate supplemental utilities to
initiate/terminate other specific exes and include them (well initiate
is usually readily available already). My first thought is to be afraid
of publicly posting a terminate example.

>
> --
> Jugoslav
> ___________
> www.geocities.com/jdujic


--

Gary Scott
mailto:gary...@ev1.net

Fortran Library
http://www.fortranlib.com

Support the GNU Fortran G95 Project: http://g95.sourceforge.net

David Frank

unread,
Jul 24, 2003, 7:44:09 AM7/24/03
to

"itooth" <ito...@yahoo.com> wrote in message
news:3f1f0c31$1...@corp.newsgroups.com...

> I am using Compaq Visual FORTRAN with WinXP.
> We have several old FORTRAN77 programs we are porting from a DEC
Alpha
> Ultrix platform to WinXP. The programs have one large FORTRAN
common block
> named datapool. Using VF I have built them as VF console
applications. How
> can I get the console applications (processes) to share the common
block?
> (Interprocess communication).
>
> I read through the newsgroup and have searched the web and even read
the
> Compaq VF user's guide:-) but I have not found an answer. Can
someone
> please explain the various ways to share the common block within VF?
>
> Thank you.
>

Ah yes, datapool
I had that on SDS-SIGMA5/7 fortran circa 1967

however, in the present world I would recommend a re-think of the
separate console apps, just merge them into one.
you might be surprised that you dont need to run them asynchronously,
but if you do, they become threads to be controlled by your NEW exec

module datapool
...............
end module datapool

program merged_console_apps_main_exec
use datapool

end program

subroutine console_app1()
use datapool

etc.

Gary L. Scott

unread,
Jul 24, 2003, 7:56:35 AM7/24/03
to

Oops, and of course I meant to say to delete it at the end as well to
avoid a memory leak.

Jugoslav Dujic

unread,
Jul 24, 2003, 8:40:03 AM7/24/03
to
Gary L. Scott wrote:
| Jugoslav Dujic wrote:
||
|| itooth wrote:
||| I am using Compaq Visual FORTRAN with WinXP.
||| We have several old FORTRAN77 programs we are porting from a DEC Alpha
||| Ultrix platform to WinXP. The programs have one large FORTRAN common block
||| named datapool. Using VF I have built them as VF console applications. How
||| can I get the console applications (processes) to share the common block?
||| (Interprocess communication).
|| - now, you can map T to an address returned by CreateShareBuffer.
|| To do it, you have to (ab)use CVF feature that a scalar pointer
|| is just an address (void* or LPVOID). || call

OpenShareBuffer("MyShareBuffer", T, iErr)
||
|| The greatest pain, I'm affraid, is that you'll have to replace all
|| occurrences of every variable X from the datapool with T%X.
|
| Don't forget to closesharebuffer at conclusion of each "slave" exe.
| This would normally be done in the "master" exe. So if possible, the
| "master" exe should be responsible for terminating the other exes in an
| orderly manner. I probably should investigate supplemental utilities to
| initiate/terminate other specific exes and include them (well initiate
| is usually readily available already). My first thought is to be afraid
| of publicly posting a terminate example.

A side issue, Gary -- may I offer a suggestion? I think the code would be
much more useful if you declare the bufferAddress to be a POINTER with
no argument checking. It's a cludge, I know, but at least in this way
you keep all the "ugliness" withing ShareBufferWin32 code, leaving user
side relatively clean. It also requires redeclaration of API interfaces.

All user has to do is to pass a *scalar pointer variable* as lpData,
and it's associated with the address returned from the API. No troubles
with Cray pointers.

If I may post a similar example of my own (wrapper around GetProp API,
which returns a LPVOID, similarly as MapViewOfFile). (Purists, please
turn your heads on the other side :-)):

!======================================================================
LOGICAL FUNCTION XGetWindowData(xWnd, lpData, sDataID)

TYPE(X_WINDOW), INTENT(IN):: xWnd
!DEC$ATTRIBUTES NO_ARG_CHECK:: lpData
INTEGER, POINTER:: lpData
CHARACTER(*), OPTIONAL, INTENT(IN):: sDataID

INTERFACE
FUNCTION GetProp (hWnd ,lpString)
USE XFTTYPES
INTEGER, POINTER:: GetProp
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_GetPropA@8' :: GetProp
!DEC$ ATTRIBUTES REFERENCE :: lpString
INTEGER hWnd
CHARACTER(*) lpString
END FUNCTION GetProp
END INTERFACE

IF (PRESENT(sDataID)) THEN
lpData => GetProp(xWnd%hWnd, TRIM(sDataID)//CHAR(0))
ELSE
lpData => GetProp(xWnd%hWnd, "XDATA"C)
END IF
XGetWindowData = ASSOCIATED(lpData)

END FUNCTION XGetWindowData


--
Jugoslav
___________
www.geocities.com/jdujic


Gary L. Scott

unread,
Jul 24, 2003, 10:06:52 PM7/24/03
to

I thought of that when designing it but I never thought it through. I
wasn't completely sure of whether that would somehow limit flexibility.
I will consider a change.


<snip>

Gary L. Scott

unread,
Jul 25, 2003, 7:43:14 AM7/25/03
to

I remember how it was supposed to work now. The main exe simply sets a
shared variable "kill flag" and the other exes monitor it and
self-terminate when required. That should usually work although
sometimes you might need to force a termination.

itooth

unread,
Jul 31, 2003, 10:38:21 PM7/31/03
to
Let me thank all who responded to my initial question.

I currently have the software running as one console application, similar to
the method David Frank described below. However, I have been reading about
the threads, specifically CreateThread and ExitThread using CVF. I looked
at some of the sample CVF programs such as the PEEKQQ example. Can anyone
expound on the pros and cons of CreateThread?

I would also like to set the priority and rate at which the thread executes.
For example some of the threads need to execute at 60 Hz while other threads
will execute at 30 Hz, 15 Hz and 7 Hz. Any suggestions for scheduling the
frequency of execution?

Thank you.


"David Frank" <dave_...@hotmail.com> wrote in message
news:dEPTa.12890$BB6.1...@twister.tampabay.rr.com...

David Frank

unread,
Aug 1, 2003, 6:59:08 AM8/1/03
to

"itooth" <ito...@yahoo.com> wrote in message
news:3f29d...@corp.newsgroups.com...

> Let me thank all who responded to my initial question.
>
> I currently have the software running as one console application,
similar to
> the method David Frank described below. However, I have been
reading about
> the threads, specifically CreateThread and ExitThread using CVF. I
looked
> at some of the sample CVF programs such as the PEEKQQ example. Can
anyone
> expound on the pros and cons of CreateThread?
>
> I would also like to set the priority and rate at which the thread
executes.
> For example some of the threads need to execute at 60 Hz while other
threads
> will execute at 30 Hz, 15 Hz and 7 Hz. Any suggestions for
scheduling the
> frequency of execution?
>
> Thank you.
>

Since you are adapting my suggestion, I will share SOME details how I
setup my realtime program RT_VIEW.
But the CVF online forum is the #1 site to technical questions.

You can run all threads synchronously at same NORMAL priority since it
is higher than exec task default IDLE priority, and since your tasks
are multiples of lowest frequency 7.5hz

re: peekqq

You probably want to monitor/execute commands linked to operator
single keystrokes, and to do that without interfering with your higher
priority tasks, you need a keyboard thread that responds to each
keystroke.


A self-scheduler would just put a
Resume 30hz task at end of alternate 60hz tasks,
Resume 15hz task at end of alternate 30hz tasks,
Resume 7.5hz task at end of alternate 15hz tasks,

Below is clipped from my RT_VIEW program which monitors stock-index
futures prices from CME (Chicago Mercantile Exchange) and plots them
for daytrading, plus other real-time site happenings around the net as
long as I can decode the site's raw html formats for realtime display
and plotting.

! - - - create/connect threads suspended at control loop
priority - - -
hKeyReadProc = CreateThread( 0, 0, KeyReadProc, 0, CREATE_SUSPENDED,
n )
hNetReadProc = CreateThread( 0, 0, NetReadProc, 0, CREATE_SUSPENDED,
n )
n = SetThreadPriority (hKeyReadProc, THREAD_PRIORITY_NORMAL )
n = SetThreadPriority (hNetReadProc, THREAD_PRIORITY_NORMAL )
n = ResumeThread (hKeyReadProc) ! activate keyboard


Note: KeyReadProc(), NetReadProc() are just normal subroutines with
NO args that become keyboard, internet read execs and have access to
exec's data module that control their functions and provides variable
scalar,array storage.

Paul Curtis

unread,
Aug 1, 2003, 11:01:43 AM8/1/03
to
CreateThread should not be used due to its well-documented memory leak.
There are thorough discussions of this issue, complete with code samples
of CVF interfaces to beginthreadex/endthreadex, on the Intel Fortran forum.
Other codes samples posted to the Forum cover how to set up multithreaded
CVF programs, in the context of multiport serial communications.

David Frank

unread,
Aug 1, 2003, 12:04:02 PM8/1/03
to
I have never experienced any problem relating to createthread memory leaks, but then how would one know using a program thats only invoked/released a couple times/day..
 
I suggest he (and you) reread last year's CLF topic "multi-threaded applications under Win2k"
where Jugoslav Dujic shuts everyone up at end of topic by posting elaborate test results with a createthread stressing diagnostic and did not see anything wrong, in fact I believe he effectively recommends use of createthread for several reasons that sounded good to me.
(but that may not be his current position).
Unless I see a problem, I wont be recoding my program for no good reason.
 
"Paul Curtis" <pcu...@kiltel.com> wrote in message news:3F2A850E...@kiltel.com...

Jugoslav Dujic

unread,
Aug 2, 2003, 2:02:49 PM8/2/03
to
|
| "Paul Curtis" <pcu...@kiltel.com> wrote in message
| news:3F2A850E...@kiltel.com...
| CreateThread should not be used due to its well-documented memory leak.
| There are thorough discussions of this issue, complete with code samples
| of CVF interfaces to beginthreadex/endthreadex, on the Intel Fortran forum.
| Other codes samples posted to the Forum cover how to set up multithreaded
| CVF programs, in the context of multiport serial communications.
David Frank wrote:
| I have never experienced any problem relating to createthread memory leaks,
| but then how would one know using a program thats only invoked/released a
| couple times/day..
|
| I suggest he (and you) reread last year's CLF topic "multi-threaded
| applications under Win2k"
| where Jugoslav Dujic shuts everyone up at end of topic by posting elaborate
| test results with a createthread stressing diagnostic and did not see
| anything wrong, in fact I believe he effectively recommends use of
| createthread for several reasons that sounded good to me.
| (but that may not be his current position).
| Unless I see a problem, I wont be recoding my program for no good reason.

Ohh, that subject again...

The discussion you refer to was actually repeated at the Forum recently
with all acters (Paul, Gerry Thomas [or was it Gary Scott? -- I tend
to mix two of them and I'm lazy now to search back] & myself) basically
staying on their positions. At the end, I took a 3rd-party tool
(www.memoryvalidator.com) and tested CreateThread on a sample application
and it indeed shown a small leakage on a call to a RTL function
(IIRC, it was 24 bytes on RANDOM_NUMBER). Then, I took Paul's translation
of _beginthreadex, but the same leakage was present there as well.

I took these results as inconclusive for either side of the argument
so I didn't posted them at the time. I'm certainly not competent enough to
interpret Memory Validator's results, since it shown other leaks of unknown
origin, on a small application I was very careful with to release everything --
CloseHandle, deallocate, DlgUnInit. Frankly, I wasn't interested in
the subject enough to bug Stephen Kelett (author of the MV) further. I'd
say that Paul's qualification that CreateThread is "unusable" is kinda
overstatement -- such small leakage, although a bit embarrasing, is
not likely to create problems on anything less than an always active
multi-user server (i.e. creating a huge number of threads and being
active 24/7).

--
Jugoslav
___________
www.geocities.com/jdujic


Gerald F. Thomas

unread,
Aug 2, 2003, 10:50:28 PM8/2/03
to

"Jugoslav Dujic" <jdujic...@uns.ns.ac.yu> wrote in message
news:bgguc8$lm180$1...@ID-106075.news.uni-berlin.de...

[...]

The root of the problem with CVF multithreading is that its runtime
doesn't properly initialize itself. This is why with CVF you'll have
memory leakage in multithreading irrespective of whether you spawn
threads via CreateThread or _beginthreadex. There is a simple
workaround but I don't feel like mentioning it again.

I'll use my formal appellation so you'll be less confused.
Dr.G.F. Thomas


0 new messages