Mips f77 and shared memory
Frank Wortner
frank at croton.enet.dec.com
Tue Feb 5 05:23:56 AEST 1991
> 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
More information about the Comp.unix.ultrix
mailing list