juh@qt.IPA.FhG.de (Juergen Henke) (02/02/91)
-- 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, which were installed. I have no problems to use shared memory in C on this machine. I would like to use COMMON blocks which are actually in shared memory. Any ideas ? Thanks in advance, Juergen P.S.: I did not see any FORTRAN statements for several years...sigh _________________________________________________________________________ Juergen Henke, e-mail juh@qt.IPA.FhG.de, PSI-mail PSI%4571109306::JUH_IPA Fraunhofer-Institut f. Produktionstechnik u. Automatisierung Eierstrasse 46, D-7000 Stuttgart 1
frank@croton.enet.dec.com (Frank Wortner) (02/05/91)
> 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 <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #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