forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

GET_GSTORAGE@ doesn't always work?
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Thu Jan 05, 2023 8:47 am    Post subject: GET_GSTORAGE@ doesn't always work? Reply with quote

hi,

I’m getting a return address of -1 from a call to:

CALL GET_GSTORAGE@ (IA, NB)

NB= ~80k (amongst other values) and has been successfully called multiple times previously - only ~1GB has been 'committed' by the application so there should be plenty of RAM available (it normally only “chokes” at ~ 2GB) and the system memory usage is less than 80%.

Is there some other condition that can cause this value to be returned?

K
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Thu Jan 05, 2023 9:05 am    Post subject: Reply with quote

Kenny

Is it a 32 bit or 64 bit application?
Back to top
View user's profile Send private message AIM Address
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Thu Jan 05, 2023 9:09 am    Post subject: Reply with quote

32 bit...

K
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Thu Jan 05, 2023 10:32 am    Post subject: Reply with quote

The essence of GET_GSTORAGE@ is a call to VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE).

In this context size (NB) is a signed 32 bit integer so values up to 2GB should work. The only way for this routine to fail is when VirtualAlloc fails.

Memory is committed from the virtual address space, not the global heap.

Looking at the Microsoft documentation for VirtualAlloc, there is no indication that MEM_RESERVE is also required in this context i.e. where the base address in not specified (is NULL).

It is just possible that a change in the operating system has meant that MEM_RESERVE is now required but this seems unlikely.
Back to top
View user's profile Send private message AIM Address
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Thu Jan 05, 2023 11:03 am    Post subject: Reply with quote

ok, tks.

i've reduced the number of calls to GET_GSTORAGE@ by setting the limit on its usage higher. previously, any request for memory > 16 bytes used GSTORAGE, <=16 used GET_STORAGE.

I've changed that decision to 256bytes and it seems better.

is there a recommended buffer size to decide which routine to call?

K
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Thu Jan 05, 2023 11:54 am    Post subject: Reply with quote

The documentation does not say anything about when to switch from GET_STORAGE@ to GET_GSTORAGE@.

Both of these routines get memory from the virtual address space.

If you prefer to get memory from the global heap (and don't want to use ALLOCATE) then you could use GET_STORAGE2@ (for a 32 bit application).

Code:
 integer addr, get_storage2@
 addr = get_storage2@(1000, 0)
 print*, addr


The second argument is no longer used.
Back to top
View user's profile Send private message AIM Address
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Thu Jan 05, 2023 1:22 pm    Post subject: Reply with quote

hmmm,

get_storage2@ works twice (the first time it returns 2147...... (i.e. approx max int*4)) and then returns 0's thereafter...

K
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Thu Jan 05, 2023 1:50 pm    Post subject: Reply with quote

Kenny

What is the context where you want to get memory? Maybe there is a more direct way.
Back to top
View user's profile Send private message AIM Address
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Thu Jan 05, 2023 3:13 pm    Post subject: Reply with quote

we make frequent use of memory addresses for storage of various data items, using two routines: vmget and vmfree. a typical situation is our dialogue handling code where we grab a number of addresses, pass them to generic field processing routines, then relaese the memory when the dialogue closes. this is legacy code and there is a LOT of it! at the moment vmget calls GET_*STORAGE@ and vmfree calls RETURN_*STORAGE@.

the only alternative i can think of is to do something like this, using a character buffer:

vmget calls ALLOCATE(ch(nb)) and passes back IAD = LOC(ch)
vmfree calls DEALLOCATE(ccore1(IAD))

which i will try now unless you can recommend something better...

K

edit: no, it doesn't work unless i keep a record in memory of all the allocated addresses and their size which is impractical, i think...
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Thu Jan 05, 2023 5:51 pm    Post subject: Reply with quote

Using ALLOCATE and DEALLOCATE in this way seems like a useful work-around but we need a direct approach to allocating memory from the global heap such as that provided by get_storage2@ which works OK for me.

Code:
 integer addr(10), get_storage2@
 do i =1, 10
 addr(i)  = get_storage2@(1000000, 0)
 write(*, "(Z8)") addr(i)
 end do
 end
Back to top
View user's profile Send private message AIM Address
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Thu Jan 05, 2023 5:56 pm    Post subject: Reply with quote

is there an equivalent return_storage2@

K
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Fri Jan 06, 2023 9:35 am    Post subject: Reply with quote

Kenny

There is an equivalent and it is called return_storage1@ but, having tested it, I find that it is not working. However, you can provide your own interface...

Code:
 integer addr(10), get_storage2@
 c_external return_storage2 '__release_memory'(VAL3)
 do i =1, 10
   addr(i)  = get_storage2@(1000000, 0)
   write(*, "(Z8)") addr(i)
 end do
 do i =1,10
   call return_storage2(addr(i))
 end do
 end
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Fri Jan 06, 2023 9:47 am    Post subject: Reply with quote

Kenny

It is probably safer if you also use your own interface for get_storage...

Code:
 c_external get_storage2    '__get_memory'(VAL3,VAL3):INTEGER*4
 c_external return_storage2 '__release_memory'(VAL3)
 integer addr(10)
 do i =1, 10
   addr(i)  = get_storage2(1000000, 0)
   write(*, "(Z8)") addr(i)
 end do
 do i =1,10
   call return_storage2(addr(i))
 end do
 end
Back to top
View user's profile Send private message AIM Address
KennyT



Joined: 02 Aug 2005
Posts: 313

PostPosted: Fri Jan 06, 2023 11:02 am    Post subject: Reply with quote

hmm,

it seems to only work partially, seems OK when all in same obj file.

but it looks like when the call to get_storage2 is in a DLL, it grabs about 60Mb memory (according to resmon) even if i've only requested 4 bytes! so my test prog soon runs out of gas.


K

MAIN:
Code:

!ftn95$free
       integer addr(10), get_storage2@
       character*4   :: ch
        c_external return_storage2@ '__release_memory'(VAL3)
      do i=1,10
      call a_vmget(4, addr(i), ir)
!      addr(i)=get_storage2@(4, 0)
      write(*, *) addr(i)
      end do
       read(*,*)ch
      do i=1,10
      call a_vmfree(addr(i))
 !     call return_storage2@(addr(i))
      write(*, *) addr(i)
      end do
       read(*,*)ch
      end


DLL:
Code:

!ftn95$free
SUBROUTINE A_VMGet (nb, IA, IRET)
  INTEGER(KIND=7)       IA, get_storage2@
      ia    =  get_storage2@(nb,0)
      return
END SUBROUTINE




!**   Free virtual memory                              *****  A_VMFree   *****
SUBROUTINE A_VMFree (IA)
 c_external return_storage2@ '__release_memory'(VAL3)
  INTEGER(KIND=7)       IA
    call return_storage2@(ia)
END SUBROUTINE


Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7550
Location: Salford, UK

PostPosted: Fri Jan 06, 2023 11:39 am    Post subject: Reply with quote

Kenny

Try using your own interface for both routines, as in my last post.

The KIND=7 should be OK but remember that this is only for 32 bit applications.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group