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