The MASM Forum

General => The Campus => Topic started by: Paulo on September 09, 2013, 09:29:41 PM

Title: Shared Memory using Masm
Post by: Paulo on September 09, 2013, 09:29:41 PM
Hi all

Can anyone give me some pointers on how to go about allocating some memory (say 20MBytes) that can be shared with other apps.
I have an app that runs all the time and logs (appends)  a value every twenty seconds or so, what I need is for another app to periodically read the data that the other app
wrote to the log.
Obviously writing to hard drive is not good as after a few months the hard drive is really getting whacked and thus prefer to use RAM.

Thanks in advance.
Paulo.
Title: Re: Shared Memory using Masm
Post by: jj2007 on September 09, 2013, 09:51:43 PM
Hi Paulo,

Perhaps you should give some more info on size and periodicity of your app. You write that the "server" writes a value (say: a double, 8 bytes) every twenty seconds, i.e. 34560 bytes per day. That is negligible for a hard disk, so why are you worried?

Does the "client" need the full log file, or just recent records?

Standard answers are memory-mapped files and WM_COPYDATA messages, but it really depends on the circumstances.
Title: Re: Shared Memory using Masm
Post by: dedndave on September 09, 2013, 10:24:21 PM
you can also create cutsom messages
but - if the second app fires up every 20 seconds - that's wearing on the hard drive, too - lol
you haven't saved anything by not doing it with a single app

how much data is to be saved svery 20 seconds ?
Title: Re: Shared Memory using Masm
Post by: Paulo on September 09, 2013, 10:37:11 PM
Hi

OK, more details:

App one ("server") is running all the time and writes 50 bytes every 20 seconds. (216 000 bytes per day).
App two ("client") will occasionally (perhaps 4 times a day) read the whole data so far for that day.

The days data is then flushed by the server at midnight.

I was under the impression that there are two types of wear and tear for hard drives:

1) The actual seeking for files (read or write)
2) Writing the actual data.
Title: Re: Shared Memory using Masm
Post by: dedndave on September 09, 2013, 10:46:35 PM
oh - 4 times a day isn't so bad
200 kb is nothing compared to the size of computer memory these days

WM_COPYDATA would work well - or a custom message

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644931%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644931%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644947%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644947%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649011%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms649011%28v=vs.85%29.aspx)

all you need is the window handle(s) in order to send messages back and forth
when the second app fires up, it can look for the first window
there are a few ways to do that - search for it by window title, or class name, etc
FindWindow, EnumWindows and so on
Title: Re: Shared Memory using Masm
Post by: jj2007 on September 09, 2013, 11:20:01 PM
Paulo,

For such a small amount of data, the simplest solution is really shared memory using a DLL. The attachment is set up for use with RichMasm, but the DLL code below works also with qEditor etc

The DLL:

include \masm32\include\masm32rt.inc

ShareLen=256*1024        ; 256k

MyData segment shared 'bss'
OneDay LABEL BYTE
  ORG $+ShareLen-1   ; looks complicated but avoids a MASM bug
  db ?
MyData ends

.code
GetPtr2SharedMem proc        ; $export
  mov eax, offset OneDay
  retn
GetPtr2SharedMem endp

LibMain proc instance:DWORD, reason:DWORD, unused:DWORD
    m2m eax, TRUE
    ret
LibMain endp

end LibMain

Sample code calling the DLL:

include \masm32\MasmBasic\MasmBasic.inc
  Init
  Dll "SharedMemInDLL"
  Declare GetPtr2SharedMem, 0
  mov edi, GetPtr2SharedMem()        ; get current content
  MsgBox 0, Cat$("Write new string?"+CrLf$+edi), "Hi", MB_YESNO
  .if eax==IDYES
        invoke MbCopy, edi, Cat$("This string was written on "+Date$+", "+Time$), -1
        MsgBox 0, "Now launch a second instance and see the string", "Hi", MB_OK
  .endif
  Exit
end start
Title: Re: Shared Memory using Masm
Post by: Paulo on September 09, 2013, 11:25:35 PM
dedndave

According to Microsoft:
"An application sends the WM_COPYDATA message to pass data to another application. "
Isn't this the opposite of what I need? (or perhaps I'm having a nebulous moment  :biggrin: having a lot of those lately).
i.e. the receiving app should first check if the other app is running (like you say via title or class) then issue a "need some data" message.

I was thinking more along the lines of the "server" app creates an array (of sorts) in memory and saves the address of that array in a file.
It only does this at start up as the address will be valid until the app closes and relinquishes that memory and deletes the file containing the memory address.
The memory array is organized so that the first 4 bytes contains a count of the bytes that it has written so far to memory.
These 4 bytes are updated every twenty seconds once the app writes the next 50 bytes.

The second app then starts up and checks for the existence of the file which has the memory address in it.
If it exists, it reads it then reads the first 4 bytes of the array in memory telling it how many bytes it must fetch from the memory.

Perhaps a bit more convoluted but I like the isolation between the two apps, i.e. no sending of messages and waiting if the other app has got it.

@jj2007

Your DLL method look interesting, I will investigate.
Title: Re: Shared Memory using Masm
Post by: Tedd on September 09, 2013, 11:26:09 PM
A disk write must be a whole sector as a minimum, so even if you only write a single byte, a whole sector must still be written. So constantly writing will produce wear. However, a modern hard-drive should be able to handle 5 years of constant reading and writing; but why waste it. And it just means the disk is unnecessarily busy for no good reason.

The OS will cache your writes to an extent, so if you write frequently enough, they will be collected and written as full sectors, but this window is only a few seconds.

Rather than shared memory (all results lost if anything goes wrong), you can still buffer your writes, and flush to file periodically.
Allocate a medium sized buffer (16--32kB) and write your results to this every 20 seconds, then when it gets 'full,' open the file (with append) and write the collected results to the file, close the file, and start filling the buffer again. The server will be able to pick up the results from this file as needed; if you strictly want up-to-the-second results, you could have the server send a message to force the client to flush its buffer, and then the server reads from the file.
Title: Re: Shared Memory using Masm
Post by: jj2007 on September 09, 2013, 11:32:26 PM
Quote from: Tedd on September 09, 2013, 11:26:09 PM
Rather than shared memory (all results lost if anything goes wrong), you can still buffer your writes, and flush to file periodically.

You should combine the two, of course. You need to add periodic saving to the simple example above, which was only intended to demonstrate how shared memory works.
Title: Re: Shared Memory using Masm
Post by: Paulo on September 09, 2013, 11:35:54 PM
Hi Tedd

Nice idea that.
Perhaps I make the buffer hold say 10 readings (~3 minutes worth of data) thereby reducing the write to file frequency by a factor
of ten and at the same time if something goes wrong with the app and it has to be restarted, not much data is lost.

Come to think of it, for 10 X 50 bytes I don't even need a buffer, just store it in a variable.
Title: Re: Shared Memory using Masm
Post by: Paulo on September 09, 2013, 11:51:54 PM
OK decided on Tedd's idea.

@jj2007

I really like your DLL, I can see several uses for it, thank you.

@dedndave

Thanks for showing me WM_USER.
I didn't know one could send private messages.
Title: Re: Shared Memory using Masm
Post by: jj2007 on September 10, 2013, 12:41:16 AM
Quote from: Paulo on September 09, 2013, 11:51:54 PM
I really like your DLL
...
I didn't know one could send private messages.

Paulo,

I updated the example above, it's now "bss" to reduce the DLL size.

Note that the "server" can send messages also as a console app, e.g. for informing the "client" that new data are available (in case synchronisation is needed); but of course, there must be a message loop at the receiving end.
Title: Re: Shared Memory using Masm
Post by: Paulo on September 10, 2013, 01:03:15 AM
Thanks for the update jj2007, but why is the source in rtf format?
Title: Re: Shared Memory using Masm
Post by: qWord on September 10, 2013, 01:22:15 AM
If some kind of server-client structure is already available, you can also use UDP for sending the log data when they arise.
Title: Re: Shared Memory using Masm
Post by: Paulo on September 10, 2013, 01:25:15 AM
Quote from: qWord on September 10, 2013, 01:22:15 AM
If some kind of server-client structure is already available, you can also use UDP for sending the log data when they arise.

Nice idea too but no server-client structure in place.
Title: Re: Shared Memory using Masm
Post by: jj2007 on September 10, 2013, 03:07:45 AM
Quote from: Paulo on September 10, 2013, 01:03:15 AM
Thanks for the update jj2007, but why is the source in rtf format?

My laziness - I hate to press more than one key ;-)
OPT_Tgt   dll   ; target is DLL, not exe
OPT_Run   GetSharedMem   ; you can't run a DLL, so run the test app instead
OPT_Assembler   JWasm   ; ML 8+ is also OK, ML 6.15 chokes

Plain text versions attached.
Title: Re: Shared Memory using Masm
Post by: dedndave on September 10, 2013, 03:22:18 AM
i'd like to see a program written with only one key   :lol:
Title: Re: Shared Memory using Masm
Post by: jj2007 on September 10, 2013, 03:55:20 AM
Writing the code itself merits more than one key :greensml:
But when I am in "polishing mode", I want to see immediately the result, so one key for "build & run" is a must. Count how many menu items you have to click in your editor...

Rumours say there are coders who are so brilliant that they assemble their code and don't need to link it, let alone run the exe. But that's just rumours ;)
Title: Re: Shared Memory using Masm
Post by: Paulo on September 10, 2013, 03:55:42 AM
@jj2007
Many thanks.

@dedndave

Quote from: dedndave on September 10, 2013, 03:22:18 AM
i'd like to see a program written with only one key   :lol:

Can't do it with one key, but I can with two.
The "1" key and the "0" key.  :biggrin:
Title: Re: Shared Memory using Masm
Post by: dedndave on September 10, 2013, 04:13:49 AM
that's the hard way, Paulo   :biggrin:
and... at some point, you are going to press Enter, i suspect
Title: Re: Shared Memory using Masm
Post by: Antariy on September 10, 2013, 02:10:30 PM
(http://umor.onru.ru/media/prikol/15816.jpg)
Title: Re: Shared Memory using Masm
Post by: Paulo on September 10, 2013, 04:11:52 PM
Who needs an ENTER key?
00001101   00001010   :biggrin:
Title: Re: Shared Memory using Masm
Post by: dedndave on September 10, 2013, 08:10:13 PM
lol
notice the guy only has 4 digits on his hand
must be a java programmer   :lol:
Title: Re: Shared Memory using Masm
Post by: Paulo on September 10, 2013, 08:28:35 PM
Quote from: dedndave on September 10, 2013, 08:10:13 PM
lol
notice the guy only has 4 digits on his hand

Does it then mean that he is making a rude gesture?  :biggrin:
Title: Re: Shared Memory using Masm
Post by: dedndave on September 10, 2013, 08:32:42 PM
it does look like it, huh   :P
Title: Re: Shared Memory using Masm
Post by: sinsi on September 10, 2013, 09:03:43 PM
Sorry, he is the ultimate ASM programmer.
4 digits = one nybble
2 hands = 8 digits = one byte
Title: Re: Shared Memory using Masm
Post by: Paulo on September 10, 2013, 09:09:37 PM
Quote from: sinsi on September 10, 2013, 09:03:43 PM
Sorry, he is the ultimate ASM programmer.
4 digits = one nybble
2 hands = 8 digits = one byte

I'm lost for WORDS.  :P
Title: Re: Shared Memory using Masm
Post by: dedndave on September 10, 2013, 10:18:29 PM
toes maybe ?

i always hated octal - don't know why   :redface:
Title: Re: Shared Memory using Masm
Post by: FORTRANS on September 10, 2013, 10:32:28 PM
Quote from: dedndave on September 10, 2013, 10:18:29 PM
i always hated octal - don't know why

Hi,

   You could always fall back to sexagesimal, as they used up
to the middle ages.  Those wacky Babylonians did things their
way, ala Frank.

Cheers,

Steve
Title: Re: Shared Memory using Masm
Post by: Paulo on September 13, 2013, 04:43:28 PM
Imagine telling the wife or girlfriend (or both  :biggrin:) that you are playing with sexagesimal on the computer.
You would get very strange looks. :eusa_naughty: