News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

WinApi+Asm Multithreading?

Started by tomson123, February 05, 2012, 03:32:36 PM

Previous topic - Next topic

tomson123

Hello again :)
Once more I turn to you for help... Your previous hints and suggestions were incredibly helpful, especially this tutorial on masm32. It really moved all my work forward :) But now I have a different problem. The situation goes like this:
I have a program which calculates a group of linear equations in form of a matrix. All the GUI is written in raw WinApi and the algorithm is in C++. With your help I was able to write the exact same algorithm, but this time in masm assemby. Now i wanted to add multithreading(WinApi) to it. Pretty simple, nothing really sophisticated. You just write the number of threads you want and then my program runs the procedure for the algorithm just as many times. To simplify, one thread, one whole procedure. Basically it's just doing the same thing n times, simultaneously.
When using the C++ code, everything worked nice. But when I used my asm code (it is the exact duplicate of c++, but in assembly), it just crashed saying the same old stuff we've heard thousands of times - heap corruption. Now I have a pretty good idea of what heap corruption while using threads may look like, but I have absolutely no concept of how to prevent it from happening...
So my question is, does assembly require any additional... well, stuff...? To be used in multithreading?

Thank you again for all your help :)

PS I am wondering if I should store all the registers on a stack at the begining of my asm function and then pop them back... I thought this would be done automatically for me ^_^ If that is the case then please, nevermind this post, because I will feel like a total idiot for not thinking of this before :P

UPDATE: I've  used pushad and popad. Also the FPU st registers are clean. Now I get an error about overwriting protected memory while trying to call the asm function... It doesn't even go inside. I'll look into it but I'm a bit surprised, since the asm code worked fine on it's own...

mkey

Hello,

are you using the CreateThread function to create threads (a bit noobish question lol but it is what it is)? Do all the threads write in the same memory structure at the same time?

tomson123

Yes, I am a bit new to writing multithreaded programs and I am using the CreateThread function.
As to memory structures, every thread has pointers to it's own memory, allocated prior to calling the thread. I've searched for any places where i might be overwriting the same part of memory but I couldn't find any. I'm pretty sure threads do not have any shared memory part except one, from which they only read.

dedndave

it is all about the allocated memory
depending on how you allocate it, the block may not be accessible by multiple threads

certainly, things get a little tedious if multiple threads are allocating and free'ing blocks from the same heap
i doubt that's the issue

i am guessing the main thread of the process is where you allocate and free the memory
which Alloc function are you using ?

mkey

OK, so you have a program written in C++ calling a function which runs CreateThread a user selected number of times which in turn starts a number new threads from the assembly written function?  Is the function which creates threads written in asm or c++? Have you tried using an empty function instead of the algorithm function?

tomson123

I'm using new().
I tried using my C++ procedure, but not an empty asm function. I will give it a try.
The function creating threads is written in C++

UPDATE: I've just tried and empty asm function with exactly the same argument list. It worked fine.
I suppose this means that something is wrong with my asm function...

Sorry for not thinking of checking this before, i feel really ashamed...
I guess I'll just try adding my asm function step after step :)

dedndave

new() is not a good way to allocate
try HeapAlloc/HeapFree

tomson123

My C++ function uses new() as well and it works just fine... And I'm allocating memory for the asm function before creating a thread, not inside the asm function. What would make HeapAlloc better than new(), which is sufficient in former, C++ code?

mkey

Access is the problem, in the multithreaded environment. Don't know it compiling the program with MT option on would help the compiler figure out what you want to do. Instead of just doing it manually :P

MichaelW

Also, if anything is writing to the shared memory and the writes or reads cannot be done in single atomic operations, you'll need to implement some sort of synchronization.
eschew obfuscation

tomson123

Alright, so I've tried to construct my asm file from the beginning, chunk of code after chunk of code. I stopped at about 1/4th. The problem is, one time it works, another it crashes with heap corruption... I have no idea what is going on...

I think i will call it a day. I've been trying to solve this for almost all day and I'm pretty much fed up with it...

Thank you for all your help. I will continue to tackle my problem tomorrow... If you have any more suggestions, please, let me know :)

Edit: There is no shared memory. Each thread has a set of pointers to it's own place in memory.

mkey

Like dave said, you'll have to use some other function to allocate memory. For instance, GlobalAlloc will work well with threads. To make things (possibly) simple, just alloc the stuff you need from ASM.

dedndave

that was my first thought, as well
however, when he's done, he'll want the allocated block available in his C code
best to allocate and free from the same scope and context

there shouldn't be a problem allocating a block of memory with one of the API functions from C,
as opposed to using new() - these C guys - everything needs to be an "object" - lol

mkey

Well, he needs to wait for all of his threads to exit so he can do the cleanup, no? Why not do everything in asm :D

tomson123

Thank you for your advice! It was most helpful :)
To finish what I have begun, there is only 1 thing left...

Can you tell me how to pass a float argument to assembly? And vice versa...
My function call from C looks something like that

asmFunction(float * pointer1, float * pointer2, ...);

Where pointer1 and pointer2 are pointers to arrays of floats.
I need to pass those arrays as floats to FPU, process them and then return as floats to my C program.
For some reason it is not sufficient to do fld real4 ptr [address] since it returns a huge number instead of my float(which I presume, is some way of representing that float).
To make matters worse, uncle Google isn't much of a help here...

Sorry for troubling you again...