Path: utzoo!censor!geac!torsqnt!lethe!yunexus!ists!helios.physics.utoronto.ca!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker.mit.edu!bloom-beacon!deccrl!news.crl.dec.com!shlump.nac.dec.com!riscy.enet.dec.com!croton.nyo.dec.com!frank From: frank@croton.enet.dec.com (Frank Wortner) Newsgroups: comp.unix.ultrix Subject: Re: Mips f77 and shared memory Message-ID: <1892@riscy.enet.dec.com> Date: 4 Feb 91 18:23:56 GMT References: <1991Feb1.175511@qt.IPA.FhG.de> Sender: newsdaemon@riscy.enet.dec.com Reply-To: frank@croton.enet.dec.com (Frank Wortner) Organization: Digital Equipment Corporation Lines: 145 > Is it possible to work with shared memory in Fortran on a DECstation (Ultrix > V4.x) ? > I am porting an application from VMS to Ultrix which did the interprocess > communication > via named COMMONs [...] Shared common areas do seem to be the Holy Grail of FORTRAN programming (at least this week). Here's a way that works. Basically, you need two bits of support. The first is a C subroutine that sets up your shared memory segment, and the second is an assembly language file that turns the common names into absolute symbols whose value is the beginning of the shared memory area. The whole thing works reasonably well and requires minimal changes to the FORTRAN code. I've enclosed a short demonstration program for your amusement. Extract the shar archive and then compile the resulting files like so: f77 shared.f common.s shminit.c Now run the executable. Change a value or two and then start a second session with the same image. You can either put the first in the backgound ("control-Z" it), or, if you're on a workstation, just start another terminal session. Then reinvoke a.out, and you'll see the changes you made in the first session. This program is a quick hack, so no comments about the ugly style, lack of comments, etc. At least it works! Extending this program, making the interface more general or cleaner , and adding additional shared common areas are left as exercises for the reader. Enjoy, Frank Just call me "Dr. Fortran." :-) -------------------------Snip Here------------------------------ #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./shared.f` then echo "writing ./shared.f" cat > ./shared.f << '\End\Of\Shar\' common /shared/ i(10) integer n write(6,100) 100 format('Shared memory tester') call shminit 20 write(6,101) 101 format('Enter 1 through 10 to change a memory location') write(6,102) 102 format('Enter any other number to view the memory') read(5,103) n 103 format(i5) if(n.ge.1 .and. n.le.10) then call change(i, n) else call display(i) endif goto 20 end c c Change a value in the shared common array c subroutine change(i,n) integer i(10) write(6,101) 101 format('Please enter a new value:') read(5,100) ivalue 100 format(i5) i(n) = ivalue return end c c Display the shared common array c subroutine display(i) integer i(10) write (*,100) (i(n), n=1,10) 100 format(10i6) return end \End\Of\Shar\ else echo "will not over write ./shared.f" fi if `test ! -s ./common.s` then echo "writing ./common.s" cat > ./common.s << '\End\Of\Shar\' .globl shared_ /* ** Shared memory is attached at 0x800000. Force the ** FORTRAN common block to be an absolute address. */ shared_ = 0x800000 \End\Of\Shar\ else echo "will not over write ./common.s" fi if `test ! -s ./shminit.c` then echo "writing ./shminit.c" cat > ./shminit.c << '\End\Of\Shar\' #include #include #include #include #define KEY 100 /* An arbitrary number */ #define SIZE 40 /* 10 32-bit integers */ /* This subroutine is called from a FORTRAN main program --- ** notice the trailing underscore! It creates a shared memory ** segment and then returns. */ void shminit_() { int shmid; char *addr; shmid = shmget(KEY, SIZE, IPC_CREAT|0666); if (shmid < 0) { perror("shminit: shmget failed: "); exit(1); } if ((int)(addr = shmat(shmid, 0, 0)) < 0) { perror("shminit: shmat failed: "); exit(2); } fprintf(stderr, "Shared memory attached at 0x%x\n", addr); } \End\Of\Shar\ else echo "will not over write ./shminit.c" fi echo "Finished archive 1 of 1" exit