public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Shared memory handling for mixed C/FORTRAN program
@ 2015-04-08 11:49 Christoph Weise
  2015-04-08 15:38 ` Marco Atzeri
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Christoph Weise @ 2015-04-08 11:49 UTC (permalink / raw)
  To: cygwin

I am porting to cygwin a program in FORTRAN/C that relies on C routines to create a shared memory region allowing various independent FORTRAN routines to share data. Program compiles and runs ok on Linux with g77/gcc compilers. I am compiling on cygwin 1.7.33-2(0.280/5/3)with gfortran/gcc (4.8.3).

One C routine creates the shared memory section of a user-defined size. This seems to work just fine, although I had to add two lines to the sys/shm.h file:


#define SHM_R        0400        /* or S_IRUGO from <linux/stat.h> */
#define SHM_W        0200        /* or S_IWUGO from <linux/stat.h> */


The shm library functions seem to return reasonable info (page size and address, for removal of the shm section).


Each FORTRAN routine then calls a C routine to find the shared memory, with a C routine returning pointers to two positions in the section intended for different kinds of data:



#define PAGESIZE 1024

int findshm(char**pptr,  /* Address of the parameter pointer */
           float**cptr)  /* Address of the data pointer */

....calls to shm library functions ....

shmaddr =0;
p =shmat(shmid,shmaddr,(SHM_R |SHM_W));
*pptr =p;
*cptr =(float*)(p +PAGESIZE);
return npages;





The calling FORTRAN code looks like this:



integer pptr,cptr
integer npages
npages =findshm(pptr,cptr)

Although the total size of the created memory section npages is ok, the amount of memory following cptr is too small on cygwin (but not in Linux) and the program crashes for larger datasets with

Program received signal SIGSEGV:Segmentationfault -invalid memory reference.

Thinking it might have to do with the different underlying data types for the pointers (integer vs char/float) in the C versus FORTRAN code, I tried changing the type definitions of the pointers within the FORTRAN routines to

byte pptr
real*4 cptr

and it all compiles and runs, but gives exactly the same runtime error, and doesn't explain why the program works in Linux.

The pointer cptr is passed to FORTRAN subroutines as

real cbuf(*)

Not sure what I can do at this point (what to look out for, where to get help), so input appreciated. 

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-08 11:49 Shared memory handling for mixed C/FORTRAN program Christoph Weise
@ 2015-04-08 15:38 ` Marco Atzeri
  2015-04-09  7:58 ` Corinna Vinschen
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Marco Atzeri @ 2015-04-08 15:38 UTC (permalink / raw)
  To: cygwin



On 4/8/2015 1:49 PM, Christoph Weise wrote:
> I am porting to cygwin a program in FORTRAN/C that relies on C routines to create a shared memory region allowing various independent FORTRAN routines to share data. Program compiles and runs ok on Linux with g77/gcc compilers. I am compiling on cygwin 1.7.33-2(0.280/5/3)with gfortran/gcc (4.8.3).
>
> One C routine creates the shared memory section of a user-defined size. This seems to work just fine, although I had to add two lines to the sys/shm.h file:
>
>
> #define SHM_R        0400        /* or S_IRUGO from <linux/stat.h> */
> #define SHM_W        0200        /* or S_IWUGO from <linux/stat.h> */

don't do that.

Instead use S_IRUSR, S_IWUSR and companions:

http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html


>
> The shm library functions seem to return reasonable info (page size and address, for removal of the shm section).
>
>
> Each FORTRAN routine then calls a C routine to find the shared memory, with a C routine returning pointers to two positions in the section intended for different kinds of data:
>
>
>
> #define PAGESIZE 1024
>
> int findshm(char**pptr,  /* Address of the parameter pointer */
>             float**cptr)  /* Address of the data pointer */
>
> ....calls to shm library functions ....
>
> shmaddr =0;
> p =shmat(shmid,shmaddr,(SHM_R |SHM_W));
> *pptr =p;
> *cptr =(float*)(p +PAGESIZE);
> return npages;
>
>
>
>
>
> The calling FORTRAN code looks like this:
>
>
>
> integer pptr,cptr
> integer npages
> npages =findshm(pptr,cptr)
>
> Although the total size of the created memory section npages is ok, the amount of memory following cptr is too small on cygwin (but not in Linux) and the program crashes for larger datasets with
>
> Program received signal SIGSEGV:Segmentationfault -invalid memory reference.
>
> Thinking it might have to do with the different underlying data types for the pointers (integer vs char/float) in the C versus FORTRAN code, I tried changing the type definitions of the pointers within the FORTRAN routines to
>
> byte pptr
> real*4 cptr
>
> and it all compiles and runs, but gives exactly the same runtime error, and doesn't explain why the program works in Linux.
>
> The pointer cptr is passed to FORTRAN subroutines as
>
> real cbuf(*)
>
> Not sure what I can do at this point (what to look out for, where to get help), so input appreciated.
>
> --
> Problem reports:       http://cygwin.com/problems.html
> FAQ:                   http://cygwin.com/faq/
> Documentation:         http://cygwin.com/docs.html
> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
>

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-08 11:49 Shared memory handling for mixed C/FORTRAN program Christoph Weise
  2015-04-08 15:38 ` Marco Atzeri
@ 2015-04-09  7:58 ` Corinna Vinschen
  2015-04-10 22:20 ` Christoph Weise
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Corinna Vinschen @ 2015-04-09  7:58 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 2302 bytes --]

On Apr  8 11:49, Christoph Weise wrote:
> I am porting to cygwin a program in FORTRAN/C that relies on C
> routines to create a shared memory region allowing various independent
> FORTRAN routines to share data. Program compiles and runs ok on Linux
> with g77/gcc compilers. I am compiling on cygwin 1.7.33-2(0.280/5/3)
> with gfortran/gcc (4.8.3).
> 
> One C routine creates the shared memory section of a user-defined
> size. This seems to work just fine, although I had to add two lines to
> the sys/shm.h file:
> 
> 
> #define SHM_R        0400        /* or S_IRUGO from <linux/stat.h> */
> #define SHM_W        0200        /* or S_IWUGO from <linux/stat.h> */

These are non-standard Linux extensions.  You should use the normal
permission bits from sys/stat.h, like S_IRUSR, S_IWUSR, etc.

> The shm library functions seem to return reasonable info (page size
> and address, for removal of the shm section).
> 
> 
> Each FORTRAN routine then calls a C routine to find the shared memory,
> with a C routine returning pointers to two positions in the section
> intended for different kinds of data:
> 
> 
> 
> #define PAGESIZE 1024

PAGESIZE on Cygwin is not 1024, and the right value to use for
XSI SHM is SHMLBA (== 64K on Cygwin)

> int findshm(char**pptr,  /* Address of the parameter pointer */
> float**cptr)  /* Address of the data pointer */
> 
> ....calls to shm library functions ....
> 
> shmaddr =0; p =shmat(shmid,shmaddr,(SHM_R |SHM_W)); *pptr =p; *cptr
> =(float*)(p +PAGESIZE); return npages;
> 
> 
> The calling FORTRAN code looks like this:
> 
> integer pptr,cptr integer npages npages =findshm(pptr,cptr)
> 
> Although the total size of the created memory section npages is ok,
> the amount of memory following cptr is too small on cygwin (but not in
> Linux) and the program crashes for larger datasets with
> 
> Program received signal SIGSEGV:Segmentationfault -invalid memory
> reference.

Does shmat actually return a non-NULL value?  Are you running
cygserver?  Did you check if it works from plain C?  If not,
do you have a simple testcase in plain C?


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-08 11:49 Shared memory handling for mixed C/FORTRAN program Christoph Weise
  2015-04-08 15:38 ` Marco Atzeri
  2015-04-09  7:58 ` Corinna Vinschen
@ 2015-04-10 22:20 ` Christoph Weise
  2015-04-11 10:18   ` Corinna Vinschen
  2015-04-11 20:25 ` Christoph Weise
  2015-04-13 11:00 ` Christoph Weise
  4 siblings, 1 reply; 10+ messages in thread
From: Christoph Weise @ 2015-04-10 22:20 UTC (permalink / raw)
  To: cygwin




Thanks for your help, your suggestions have helped me greatly but I'm still stuck. 



>> I am porting to cygwin a program in FORTRAN/C that relies on C
>> routines to create a shared memory region allowing various independent
>> FORTRAN routines to share data. Program compiles and runs ok on Linux
>> with g77/gcc compilers. I am compiling on cygwin 1.7.33-2(0.280/5/3)
>> with gfortran/gcc (4.8.3).
>> 
>> One C routine creates the shared memory section of a user-defined
>> size. This seems to work just fine, although I had to add two lines to
>> the sys/shm.h file:
>> 
>> 
>> #define SHM_R        0400        /* or S_IRUGO from <linux/stat.h> */
>> #define SHM_W        0200        /* or S_IWUGO from <linux/stat.h> */
>
>These are non-standard Linux extensions.  You should use the normal
>permission bits from sys/stat.h, like S_IRUSR, S_IWUSR, etc.


Ok, thank you, changed that.



>> The shm library functions seem to return reasonable info (page size
>> and address, for removal of the shm section).
>> 
>> 
>> Each FORTRAN routine then calls a C routine to find the shared memory,
>> with a C routine returning pointers to two positions in the section
>> intended for different kinds of data:
>> 
>> 
>> 
>> #define PAGESIZE 1024
>
>PAGESIZE on Cygwin is not 1024, and the right value to use for
>XSI SHM is SHMLBA (== 64K on Cygwin)



Setting PAGESIZE to SHMLBA creates problems elsewhere in the program (then PAGESIZE is too big for the program to handle, a problem I have yet to debug) so only unless there is no workaround (please see below) I'd like to avoid trying to use SHMLBA for the time being.

Regardless of the choice of PAGESIZE, only a total of 4kB can be stored sequentially in the shared memory section handed by shmat. If I try to write more than this number of bytes to the shm section the program crashes. 


>> int findshm(char**pptr,  /* Address of the parameter pointer */
>> float**cptr)  /* Address of the data pointer */
>> 
>> ....calls to shm library functions ....
>> 
>> shmaddr =0; p =shmat(shmid,shmaddr,(SHM_R |SHM_W)); *pptr =p; *cptr
>> =(float*)(p +PAGESIZE); return npages;
>> 
>> 
>> The calling FORTRAN code looks like this:
>> 
>> integer pptr,cptr integer npages npages =findshm(pptr,cptr)
>> 
>> Although the total size of the created memory section npages is ok,
>> the amount of memory following cptr is too small on cygwin (but not in
>> Linux) and the program crashes for larger datasets with
>> 
>> Program received signal SIGSEGV:Segmentationfault -invalid memory
>> reference.



>Does shmat actually return a non-NULL value? 

shmat seems to work as desired, the pointers it returns are being passed properly between C and Fortran


> Are you running cygserver? 

I am using the server. 


> Did you check if it works from plain C?  If not, do you have a simple testcase in plain C?

I modified the first C utlity, which sets up the shared memory section, to use the addresses it receives from shmat to try to write as much data as possible into the section. I could read/write to the full shm section from within that utility. 

I also modified a second C routine which looks for the memory section and returns addresses into the shm section. When attempting to read/write within that second routine the program crashes when accessing addresses more than 4 kB from the start of the shm section. 

I found this 
https://www.cygwin.com/ml/cygwin/2009-01/msg00492.html
and links from there, which suggest that this 4kB "barrier" is probably related to cygwin's memory handling. 

If this is in fact a likely source of the problem, is there any way to work around this 4 kB limit while continuing to use the shm library? I can think of using multiple pointers  to separate sections (perhaps as a pointer array), but that amounts to an extensive rewrite. 

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-10 22:20 ` Christoph Weise
@ 2015-04-11 10:18   ` Corinna Vinschen
  0 siblings, 0 replies; 10+ messages in thread
From: Corinna Vinschen @ 2015-04-11 10:18 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 2599 bytes --]

On Apr 10 22:20, Christoph Weise wrote:
> >PAGESIZE on Cygwin is not 1024, and the right value to use for
> >XSI SHM is SHMLBA (== 64K on Cygwin)
> 
> Setting PAGESIZE to SHMLBA creates problems elsewhere in the program
> (then PAGESIZE is too big for the program to handle, a problem I have
> yet to debug) so only unless there is no workaround (please see below)
> I'd like to avoid trying to use SHMLBA for the time being.

The PAGESIZE is an OS-specific value.  If you set it to some arbitrary
value and use it for your own purposes it's ok, but if the application
expects the OS to follow its lead, you'll run into problems.

> Regardless of the choice of PAGESIZE, only a total of 4kB can be
> stored sequentially in the shared memory section handed by shmat. If I
> try to write more than this number of bytes to the shm section the
> program crashes. 

Not that I know of.

> > Did you check if it works from plain C?  If not, do you have a
> > simple testcase in plain C?
> 
> I modified the first C utlity, which sets up the shared memory
> section, to use the addresses it receives from shmat to try to write
> as much data as possible into the section. I could read/write to the
> full shm section from within that utility. 

Which means, the memory has been allocated the right size.

> I also modified a second C routine which looks for the memory section
> and returns addresses into the shm section. When attempting to
> read/write within that second routine the program crashes when
> accessing addresses more than 4 kB from the start of the shm section. 

Is that inside the same executable?

> I found this 
> https://www.cygwin.com/ml/cygwin/2009-01/msg00492.html
> and links from there, which suggest that this 4kB "barrier" is probably related to cygwin's memory handling. 

That has nothing to do with it.  It's just a question I replied to.
Cygwin always returns memory in 64K chunks because that's what the
underlying OS does.

Unless the OS is asked to return shared memory backed by a file.  In
this case it returns memory ending on a 4K boundary.  That's weird, but
Cygwin has code trying to workaround this problem.  But that doesn't
affect shmat.

> If this is in fact a likely source of the problem,

No, it isn't.  If you can provide a simple testcase in plan C which
allows to reproduce the issue with minimal code, I'd take a look into
the issue.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-08 11:49 Shared memory handling for mixed C/FORTRAN program Christoph Weise
                   ` (2 preceding siblings ...)
  2015-04-10 22:20 ` Christoph Weise
@ 2015-04-11 20:25 ` Christoph Weise
  2015-04-12 11:23   ` Corinna Vinschen
  2015-04-13 11:00 ` Christoph Weise
  4 siblings, 1 reply; 10+ messages in thread
From: Christoph Weise @ 2015-04-11 20:25 UTC (permalink / raw)
  To: cygwin

>On Apr 10 22:20, Christoph Weise wrote:
>> >PAGESIZE on Cygwin is not 1024, and the right value to use for
>> >XSI SHM is SHMLBA (== 64K on Cygwin)
>> 
>> Setting PAGESIZE to SHMLBA creates problems elsewhere in the program
>> (then PAGESIZE is too big for the program to handle, a problem I have
>> yet to debug) so only unless there is no workaround (please see below)
>> I'd like to avoid trying to use SHMLBA for the time being.
>
>The PAGESIZE is an OS-specific value.  If you set it to some arbitrary
>value and use it for your own purposes it's ok, but if the application
>expects the OS to follow its lead, you'll run into problems.
>
>> Regardless of the choice of PAGESIZE, only a total of 4kB can be
>> stored sequentially in the shared memory section handed by shmat. If I
>> try to write more than this number of bytes to the shm section the
>> program crashes. 
>
>Not that I know of.



Please see below. 


>> > Did you check if it works from plain C?  If not, do you have a
>> > simple testcase in plain C?
>> 
>> I modified the first C utlity, which sets up the shared memory
>> section, to use the addresses it receives from shmat to try to write
>> as much data as possible into the section. I could read/write to the
>> full shm section from within that utility. 
>
>Which means, the memory has been allocated the right size.
>
>> I also modified a second C routine which looks for the memory section
>> and returns addresses into the shm section. When attempting to
>> read/write within that second routine the program crashes when
>> accessing addresses more than 4 kB from the start of the shm section. 
>
>Is that inside the same executable?


No, they are separate executables, please see below. 


>
>> I found this 
>> https://www.cygwin.com/ml/cygwin/2009-01/msg00492.html
>> and links from there, which suggest that this 4kB "barrier" is probably related to cygwin's memory handling. 
>
>That has nothing to do with it.  It's just a question I replied to.
>Cygwin always returns memory in 64K chunks because that's what the
>underlying OS does.
>
>Unless the OS is asked to return shared memory backed by a file.  In
>this case it returns memory ending on a 4K boundary.  That's weird, but
>Cygwin has code trying to workaround this problem.  But that doesn't
>affect shmat.
>
>> If this is in fact a likely source of the problem,
>
>No, it isn't.  If you can provide a simple testcase in plan C which
>allows to reproduce the issue with minimal code, I'd take a look into
>the issue.
>



Please see below, I provide minimal C code for three separate executables, one creates the shm section, another finds it, the third removes it. I include also a bash test script that executes the routines in order. Please beware as I removed some checks to reduce the length of the code, but it should run ok. The PAGESIZE parameter is hardcoded (here 512 bytes). The desired shared mem section size is set interactively as input to makeshm, or automatically with the bash script. 

I can write to the shm section with the second routine when the requested section <= 4096 bytes. Otherwise it's not happy. 

Thanks for your help.


#####################################################################
bash test script
#####################################################################

#!/bin/bash
./makeshm <<EOF
4096
EOF

# try >4096 for a seg fault

# check for shms
ipcs

./findshm

./removeshm

# check for shms
ipcs


#####################################################################
makeshm.c
#####################################################################
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>

#undef  PAGESIZE
#define PAGESIZE 512

#define MYKEY		0xEDCB		/* A code for our workspaces */

#ifndef IPC_ALLOC
#define IPC_ALLOC	0
#endif

int main(int argc, char **argv)
{
unsigned	uid;
key_t	key;
int		shmid;
int 	shmsuccess;
struct 	shmid_ds	sbuf;
int		i, size;
char	*p, *shmaddr;
char	answer[10];

printf("-------------IN MAKESHM----------------\n");

/* Check for override environment variable set */
uid = getuid();
key = (MYKEY << 16) | (uid & 0xFFFF);

shmid = shmget(key, PAGESIZE, IPC_ALLOC);
if (shmid < 0){
printf("Creating the shared memory section\n");

/* Now try to create it */
printf("Enter buffer size (bytes): "); 
fgets(answer, sizeof(answer), stdin);
i = sscanf(answer, "%d", &size);
printf("%d\n",size);
shmid = shmget(key, size, IPC_CREAT | 0666);
}
else {
perror("Could not create shared memory section");
return 1;
}

/* Print the section information */
shmsuccess = shmctl(shmid, IPC_STAT, &sbuf);

/* Attach to the shared memory section */
shmaddr = 0;
p = shmat(shmid, shmaddr, (S_IRUSR | S_IWUSR)); 

if (-1 == (int) p)
perror("Unable to attach to the section\n");
else {
printf("Attached at address %x.\n", p); 
}

/* !!! hardcoded !!! */
int foffset = 1020;

printf("Check writing into the buffer at addresses starting at %x + %d bytes (buffer size: %d bytes)\n",p,4*foffset,sbuf.shm_segsz); 

float *pfloop = (float*) (p + foffset*4);
float *piorig = (float*)p;

*piorig = (float)0; 
printf("storing in address %x (%x + %d floats):  %f\n",piorig,piorig,0,*piorig);
printf(" .................\n");

for (i=0;i<sbuf.shm_segsz/4 -foffset;i++,pfloop++) {
*pfloop = (float)(i+foffset); 
printf("storing in address %x (%x + %d floats):  %f\n",pfloop,piorig,i+foffset,*pfloop);
}
printf("--------------------------------------------\n");

/* Detach from the memory section */ 
if (0 == shmdt(p))
printf("Detached from the shared memory section.\n");
else
perror("Could not detach the section");

return 0;
}



#####################################################################
removeshm.c
#####################################################################
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#undef  PAGESIZE
#define PAGESIZE 512

#define MYKEY		0xEDCBu		/* A code for our workspaces */

#ifndef IPC_ALLOC
#define IPC_ALLOC	0
#endif

int main(int argc, char **argv)
{
unsigned	uid;
key_t	key;
int		shmid;
struct 	shmid_ds	sbuf;
int		i;

printf("-------------IN REMOVESHM----------------\n");

uid = getuid();
key = (MYKEY << 16) | (uid & 0xFFFF);

shmid = shmget(key, PAGESIZE, IPC_ALLOC);

i = shmctl(shmid, IPC_RMID, &sbuf);
if (0 == i)
printf("Removal was successful.\n");
else {
perror("Error in removal");
return 1;
}

return 0;
}




#####################################################################
findshm.c
#####################################################################
#include <stdio.h>
#include <stdlib.h>
#include <string.h>  			/* memcpy */

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>

#undef  PAGESIZE
#define PAGESIZE 512

#define MYKEY		0xEDCBu		/* A code for our workspaces */

#ifndef IPC_ALLOC
#define IPC_ALLOC	0
#endif 

int main(int argc, char **argv)
{
int		uid;
key_t	key;
int		shmid;
int		shmsuccess;
char	*p, *shmaddr;
struct  shmid_ds	sbuf;
int		npages;

printf("-------------IN RUNME/FINDSHM----------------\n");
printf("Mapping the shared memory section ... \n"); 

uid = getuid();

/* See that the section exists */
key = (MYKEY << 16) | (uid & 0xFFFF);
shmid = shmget(key, PAGESIZE, IPC_ALLOC);

/* Determine the shared memory size */
shmsuccess=shmctl(shmid, IPC_STAT, &sbuf);

/* Attach to the shared memory section and check for other users */
shmaddr = 0;
p = shmat(shmid, shmaddr, (S_IRUSR | S_IWUSR)); 

if (-1 == (int) p) {
perror("Unable to attach to the section\n");
return -1; 
}
else {
printf("Attached at address %x.\n", p); 
}

/* Store the pointers */

char *pptr = p;
float *cptr = (float *) (p + PAGESIZE);


printf("--------------------------------------------\n");
printf("Checking memory pointers \n");
printf("pptr: %x\n",pptr);
printf("cptr: %x\n",cptr);
printf("cptr-pptr: %i\n",((char *)(cptr))-(pptr));
printf("--------------------------------------------\n");



/*check contents of buffer */

int i, foffset = 1020;

printf("Check writing into the buffer at addresses starting at %x + %d bytes (buffer size: %d bytes)\n",p,4*foffset,sbuf.shm_segsz);

float *pfloop = (float*) (p + foffset*4);
float *piorig = (float*) p;

*piorig = (float)0; 
printf("storing in address %x (%x + %d floats):  %f\n",piorig,piorig,0,*piorig);
printf(" .................\n");

for (i=0;i<sbuf.shm_segsz/4 -foffset;i++,pfloop++) {
printf("content of address %x (%x + %d floats):  %f\n",pfloop,piorig,i+foffset,*pfloop); 
*pfloop = (float)2*(i+foffset); 
printf("storing in address %x (%x + %d floats):  %f\n",pfloop,piorig,i+foffset,*pfloop);
}
printf("--------------------------------------------\n");

return 0;
}




#####################################################################
#./makefile#
#####################################################################

.SUFFIXES:	.f .c .o .a

CC=			gcc
CFLAGS=		-c  -ansi 

.c.o:
$(CC) $(CFLAGS)  -c $<

EXEFILES=		makeshm removeshm findshm

all:		$(EXEFILES)

makeshm:		 makeshm.c
$(CC)    makeshm.c -o   makeshm.exe 
chmod 4755 makeshm.exe 

removeshm:		 removeshm.c
$(CC)    removeshm.c -o   removeshm.exe 
chmod 4755 removeshm.exe 

findshm:		 findshm.c
$(CC)    findshm.c -o   findshm.exe 


#
# Cleanup of non-source files
#

clean:
rm -f 2>/dev/null *~  *.o *.exe


#####################################################################
typical output
#####################################################################

$ ./test1.exe
-------------IN MAKESHM----------------
Creating the shared memory section
Enter buffer size (bytes): 4096
Attached at address 7fea0000.
Check writing into the buffer at addresses starting at 7fea0000 + 4080 bytes (buffer size: 4096 bytes)
storing in address 7fea0000 (7fea0000 + 0 floats):  0.000000
.................
storing in address 7fea0ff0 (7fea0000 + 1020 floats):  1020.000000
storing in address 7fea0ff4 (7fea0000 + 1021 floats):  1021.000000
storing in address 7fea0ff8 (7fea0000 + 1022 floats):  1022.000000
storing in address 7fea0ffc (7fea0000 + 1023 floats):  1023.000000
--------------------------------------------
Detached from the shared memory section.
Message Queues:
T     ID               KEY        MODE       OWNER    GROUP

Shared Memory:
T     ID               KEY        MODE       OWNER    GROUP
m 12845056           3989505001 --rw-rw-rw-     John     None

Semaphores:
T     ID               KEY        MODE       OWNER    GROUP

-------------IN RUNME/FINDSHM----------------
Mapping the shared memory section ...
Attached at address 7fea0000.
--------------------------------------------
Checking memory pointers
pptr: 7fea0000
cptr: 7fea0200
cptr-pptr: 512
--------------------------------------------
Check writing into the buffer at addresses starting at 7fea0000 + 4080 bytes (buffer size: 4096 bytes)
storing in address 7fea0000 (7fea0000 + 0 floats):  0.000000
.................
content of address 7fea0ff0 (7fea0000 + 1020 floats):  1020.000000
storing in address 7fea0ff0 (7fea0000 + 1020 floats):  2040.000000
content of address 7fea0ff4 (7fea0000 + 1021 floats):  1021.000000
storing in address 7fea0ff4 (7fea0000 + 1021 floats):  2042.000000
content of address 7fea0ff8 (7fea0000 + 1022 floats):  1022.000000
storing in address 7fea0ff8 (7fea0000 + 1022 floats):  2044.000000
content of address 7fea0ffc (7fea0000 + 1023 floats):  1023.000000
storing in address 7fea0ffc (7fea0000 + 1023 floats):  2046.000000
--------------------------------------------
-------------IN REMOVESHM----------------
Removal was successful.
Message Queues:
T     ID               KEY        MODE       OWNER    GROUP

Shared Memory:
T     ID               KEY        MODE       OWNER    GROUP

Semaphores:
T     ID               KEY        MODE       OWNER    GROUP

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-11 20:25 ` Christoph Weise
@ 2015-04-12 11:23   ` Corinna Vinschen
  2015-04-12 12:18     ` Corinna Vinschen
  0 siblings, 1 reply; 10+ messages in thread
From: Corinna Vinschen @ 2015-04-12 11:23 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1798 bytes --]

On Apr 11 20:25, Christoph Weise wrote:
> Please see below, I provide minimal C code for three separate
> executables, one creates the shm section, another finds it, the third
> removes it. I include also a bash test script that executes the
> routines in order.

Thanks,

> Please beware as I removed some checks to reduce
> the length of the code, but it should run ok. The PAGESIZE parameter
> is hardcoded (here 512 bytes). The desired shared mem section size is
> set interactively as input to makeshm, or automatically with the bash
> script. 

Ok, but there are bugs in the code which result in GCC warnings.  I
don't know which of them are part of your original code, but they are
really a problem.

  if ((int) -1 == p)

Don't check a pointer against an int value.  It won't work on a 64 bit
platform.  Make that

  if ((void *) -1 == p)

For the same reason, don't use %x to printf a pointer.  Use %tx.

> I can write to the shm section with the second routine when the requested section <= 4096 bytes. Otherwise it's not happy. 

The problem is the call to shmget:

  #undef  PAGESIZE
  #define PAGESIZE 512
  shmid = shmget(key, PAGESIZE, IPC_ALLOC);

Since you're requesting only 512 bytes, the shared memory segment the
following shmat call returns is only 4K.  The shmget call should request
as much memory as it needs so that the OS call is called with the right
view size.

I re-read the POSIX man page for shmget, and it doesn't mention anything
which would point out that Cygwin's behaviour here is wrong.  If anybody
has more information on this, please share them.


HTH,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-12 11:23   ` Corinna Vinschen
@ 2015-04-12 12:18     ` Corinna Vinschen
  0 siblings, 0 replies; 10+ messages in thread
From: Corinna Vinschen @ 2015-04-12 12:18 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 2240 bytes --]

On Apr 12 13:23, Corinna Vinschen wrote:
> On Apr 11 20:25, Christoph Weise wrote:
> > Please see below, I provide minimal C code for three separate
> > executables, one creates the shm section, another finds it, the third
> > removes it. I include also a bash test script that executes the
> > routines in order.
> 
> Thanks,
> 
> > Please beware as I removed some checks to reduce
> > the length of the code, but it should run ok. The PAGESIZE parameter
> > is hardcoded (here 512 bytes). The desired shared mem section size is
> > set interactively as input to makeshm, or automatically with the bash
> > script. 
> 
> Ok, but there are bugs in the code which result in GCC warnings.  I
> don't know which of them are part of your original code, but they are
> really a problem.
> 
>   if ((int) -1 == p)
> 
> Don't check a pointer against an int value.  It won't work on a 64 bit
> platform.  Make that
> 
>   if ((void *) -1 == p)
> 
> For the same reason, don't use %x to printf a pointer.  Use %tx.
> 
> > I can write to the shm section with the second routine when the requested section <= 4096 bytes. Otherwise it's not happy. 
> 
> The problem is the call to shmget:
> 
>   #undef  PAGESIZE
>   #define PAGESIZE 512
>   shmid = shmget(key, PAGESIZE, IPC_ALLOC);
> 
> Since you're requesting only 512 bytes, the shared memory segment the
> following shmat call returns is only 4K.  The shmget call should request
> as much memory as it needs so that the OS call is called with the right
> view size.
> 
> I re-read the POSIX man page for shmget, and it doesn't mention anything
> which would point out that Cygwin's behaviour here is wrong.  If anybody
> has more information on this, please share them.

On second thought, adjusting Cygwin's behaviour to Linux here is rather
trivial.  I applied a patch to the git repo and uploaded new developer
snapshots (2015-04-12) to https://cygwin.com/snapshots/
You only have to replace the DLL itself, cygserver is not affected by
this patch.  Please give it a try.


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-08 11:49 Shared memory handling for mixed C/FORTRAN program Christoph Weise
                   ` (3 preceding siblings ...)
  2015-04-11 20:25 ` Christoph Weise
@ 2015-04-13 11:00 ` Christoph Weise
  2015-04-14  7:39   ` Corinna Vinschen
  4 siblings, 1 reply; 10+ messages in thread
From: Christoph Weise @ 2015-04-13 11:00 UTC (permalink / raw)
  To: cygwin



> The problem is the call to shmget:
> 
>   #undef  PAGESIZE
>   #define PAGESIZE 512
>   shmid = shmget(key, PAGESIZE, IPC_ALLOC);
> 
> Since you're requesting only 512 bytes, the shared memory segment the
> following shmat call returns is only 4K.  The shmget call should request
> as much memory as it needs so that the OS call is called with the right
> view size.
> 
> I re-read the POSIX man page for shmget, and it doesn't mention anything
> which would point out that Cygwin's behaviour here is wrong.  If anybody
> has more information on this, please share them.

Yes, you're right. I tried a workaround that uses a second shm section to pass between executables either the size or more simply the shm ID of the main shm section. Either way this circumvented the problem.

However with this solution there is an odd change in the base address of the shm section between calls from the routine that creates the section to the executables that use it. I may be using the shm library inappropriately but my guess is that the OS/cygwin is doing something in the background (making a copy of the data?). Just for reference here's sample output:

$ $ ./test1.exe
storing in address 7fea0000 (7fea0000 + 0 floats):  0.000000
.................
storing in address 7fea0fec (7fea0000 + 1019 floats):  1019.000000
storing in address 7fea0ff0 (7fea0000 + 1020 floats):  1020.000000
storing in address 7fea0ff4 (7fea0000 + 1021 floats):  1021.000000
storing in address 7fea0ff8 (7fea0000 + 1022 floats):  1022.000000
storing in address 7fea0ffc (7fea0000 + 1023 floats):  1023.000000
--------------------------------------------
Detached from the shared memory section.
Attached at second address 7fea0000.
Message Queues:
T     ID               KEY        MODE       OWNER    GROUP

Shared Memory:
T     ID               KEY        MODE       OWNER    GROUP
m 1179648           3989570537 --rw-rw-rw-     John     John
m 131073           3989505001 --rw-rw-rw-     John     John

Semaphores:
T     ID               KEY        MODE       OWNER    GROUP

-------------IN RUNME/FINDSHM----------------
Mapping the shared memory section ...
This is the key: -305396759.
size of section should be 4096.
Got this far (shmid : 131073).
Size of section: 4096.
Attached at address 7fe90000.
--------------------------------------------
Checking memory pointers
pptr: 7fe90000
cptr: 7fe90200
cptr-pptr: 512
--------------------------------------------
Check writing into the buffer at addresses starting at 7fe90000 + 4076 bytes (buffer size: 4096 bytes)
storing in address 7fe90000 (7fe90000 + 0 floats):  0.000000
.................
content of address 7fe90fec (7fe90000 + 1019 floats):  1019.000000
storing in address 7fe90fec (7fe90000 + 1019 floats):  2038.000000
content of address 7fe90ff0 (7fe90000 + 1020 floats):  1020.000000
storing in address 7fe90ff0 (7fe90000 + 1020 floats):  2040.000000
content of address 7fe90ff4 (7fe90000 + 1021 floats):  1021.000000
storing in address 7fe90ff4 (7fe90000 + 1021 floats):  2042.000000
content of address 7fe90ff8 (7fe90000 + 1022 floats):  1022.000000
storing in address 7fe90ff8 (7fe90000 + 1022 floats):  2044.000000
content of address 7fe90ffc (7fe90000 + 1023 floats):  1023.000000
storing in address 7fe90ffc (7fe90000 + 1023 floats):  2046.000000




>On second thought, adjusting Cygwin's behaviour to Linux here is rather
>trivial.  I applied a patch to the git repo and uploaded new developer
>snapshots (2015-04-12) to https://cygwin.com/snapshots/
>You only have to replace the DLL itself, cygserver is not affected by
>this patch.  Please give it a try.

That did the trick. With the new cygwin1 DLL I don't need to pass shm section information between executables and the overall behavior is consistent with that on Linux.

Thank you for your help! I am very happy this works now on cygwin.

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Shared memory handling for mixed C/FORTRAN program
  2015-04-13 11:00 ` Christoph Weise
@ 2015-04-14  7:39   ` Corinna Vinschen
  0 siblings, 0 replies; 10+ messages in thread
From: Corinna Vinschen @ 2015-04-14  7:39 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1950 bytes --]

On Apr 13 11:00, Christoph Weise wrote:
> 
> 
> > The problem is the call to shmget:
> > 
> >   #undef  PAGESIZE
> >   #define PAGESIZE 512
> >   shmid = shmget(key, PAGESIZE, IPC_ALLOC);
> > 
> > Since you're requesting only 512 bytes, the shared memory segment the
> > following shmat call returns is only 4K.  The shmget call should request
> > as much memory as it needs so that the OS call is called with the right
> > view size.
> > 
> > I re-read the POSIX man page for shmget, and it doesn't mention anything
> > which would point out that Cygwin's behaviour here is wrong.  If anybody
> > has more information on this, please share them.
> 
> Yes, you're right. I tried a workaround that uses a second shm section to pass between executables either the size or more simply the shm ID of the main shm section. Either way this circumvented the problem.
> 
> However with this solution there is an odd change in the base address
> of the shm section between calls from the routine that creates the
> section to the executables that use it.

You can't rely on getting the shm region allocated at the same memory
address in different executables.

> >On second thought, adjusting Cygwin's behaviour to Linux here is rather
> >trivial.  I applied a patch to the git repo and uploaded new developer
> >snapshots (2015-04-12) to https://cygwin.com/snapshots/
> >You only have to replace the DLL itself, cygserver is not affected by
> >this patch.  Please give it a try.
> 
> That did the trick. With the new cygwin1 DLL I don't need to pass shm
> section information between executables and the overall behavior is
> consistent with that on Linux.
> 
> Thank you for your help! I am very happy this works now on cygwin.

Thanks for the feedback.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-04-14  7:39 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-08 11:49 Shared memory handling for mixed C/FORTRAN program Christoph Weise
2015-04-08 15:38 ` Marco Atzeri
2015-04-09  7:58 ` Corinna Vinschen
2015-04-10 22:20 ` Christoph Weise
2015-04-11 10:18   ` Corinna Vinschen
2015-04-11 20:25 ` Christoph Weise
2015-04-12 11:23   ` Corinna Vinschen
2015-04-12 12:18     ` Corinna Vinschen
2015-04-13 11:00 ` Christoph Weise
2015-04-14  7:39   ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).