For a reason I need to allocate 757 120 Byte, and I've tried the following:
Attempting (and failing) with using CreateHeap, HeapAlloc; I've given up on that now...
Using the BSs (.data?) section, I'm using this and there is only one problem (one against 743 errror using the above way...) speed/time. I takes forever to compile, so I wonder if I (or you :) ) can speed up the process?

When I first tried:
_test_ db 520*1456 dup (?)
it took forever, so I thought may bee an larger data type is faster so I tried:
_test_ dd (757120/4) dup (?)
it too is too slow, so I finally tried:
_test_ qword (757120/8) dup (?)
it's also too damn slow.

As I said I've tried the HeapAlloc thing, it doesn't work (data written and read is not matching, why :confused: ), the slow way is working perfectly though. Any suggestions? (I have a struct every 520 byte so it must work with that).

It's is Friday the 13th... (may bee I'm too tired and simply have a bad luck with HeapAlloc...)
Posted on 2002-09-13 14:00:08 by scientica
Put it in a separate object file and just LINK it in. Use NMAKE to automate the rebuild when changes are made to second file. ;)
Posted on 2002-09-13 14:14:19 by bitRAKE
Can't understand why HeapAlloc doesn't work, but
invoke GlobalAlloc,GPTR,757120
certainly should.
Posted on 2002-09-13 17:14:53 by Eóin
If you specified dwMaximumSize calling HeapCreate, have you read this?
"If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8."

You can speed up Heap manager spicifying HEAP_NO_SERIALIZE flag in flOptions parameter,
if you know for sure that only one thread have acess to the heap.
If HEAP_NO_SERIALIZE is not set heap manager will not create synchronisation object (mutex) to syncronize acess to the heap. It works faster.
Also don't add HEAP_ZERO_MEMORY flag if you really don't need it.
How do you create/alloc heap?

AFAIK, the fastest way to allocate/manage memory is to create Memory Map File (CreateFileMapping).
Because all other methods (CreateHeap, VirtualAlloc etc.) are based on MMF.
Posted on 2002-09-14 04:07:11 by Four-F
GetProcessHeap - to get the handle to the heap...
HeapAlloc
HeapFree
Posted on 2002-09-14 04:10:20 by stryker
Four-F, I've read it, but I never thougt that might be the problem (the size I need is 0B 8D80h witch is greater than 7 FFF8h).

I created the heap via "invoke HeapCreate,HEAP_GENERATE_EXCEPTIONS,520,1456*520", but since the dwMaximumSize is larget then allowed this doesn't work, they direct me to VirtualAlloc. I'd rather not like to play with the HeapAlloc or other such function, I simply want an array of this 520 byte struct that is simple to access. The HEAP_NO_SERIALIZE, how dumb am I? (I read the description as this "to allow multithreading", while it is "only allows one process to access the heap at a time"...)

bitRAKE, said "Put it in a separate object file and just LINK it in. Use NMAKE to automate the rebuild when changes are made to second file."
It sound like an good idea, since the slow way is working and I have to get over this problem soon; I must continue with the project I'm working on now, and this has stalled it some what, for now speed isn't the to priority (it will be a later project to optimize), there is one problem though, I know I have a copy of NMAKE somwhere but I don't have any clue what so ever how to use NMAKE, it there some manual I can read (or do one of you know the arguments I need to send)?
Posted on 2002-09-14 04:55:33 by scientica
but since the dwMaximumSize is larget then allowed this doesn't work
OK. You understand.

(I read the description as this "to allow multithreading"...
Because of my far from good knowledge of english, let me quote:

By default, a heap will serialize access to itself so that multiple threads can allocate and free blocks from the heap without the danger of corrupting the heap. When an attempt is made to allocate a block of memory from the heap, the HeapAlloc function (discussed later) must do the following:

1.Traverse the linked list of allocated and freed memory blocks
2. Find the address of a free block
3. Allocate the new block by marking the free block as allocated
4. Add a new entry to the linked list of memory blocks

Here's an example that illustrates why you should avoid using the HEAP_NO_SERIALIZE flag.
Let's say that two threads attempt to allocate blocks of memory from the same heap at the same time.
Thread 1 executes steps 1 and 2 above and gets the address of a free memory block.
However, before Thread 1 can execute step 3, it is preempted and Thread 2 gets a chance to execute steps 1 and 2.
Because Thread 1 has not yet executed step 3, Thread 2 finds the address to the same free memory block.

With both threads having found what they believe to be a free memory block in the heap,
Thread 1 updates the linked list, marking the new block as allocated.
Thread 2 then also updates the linked list, marking the same block as allocated.
Neither thread has detected a problem so far, but both threads receive an address to the exact same block of memory.

This type of bug can be very difficult to track down because it usually doesn't manifest itself immediately.

J. Richter

It was about avoiding HEAP_NO_SERIALIZE in multy-threaded processes. But...

The system acomplishes serialization of heap (allows only one thread have access to the heap at the same time)
by creating internal mutex object. If thread try to have access (allocate/free) to the heap,
system sets mutex to non-signaled state (if mutex is not owned).
If another thread wants to access (allocate/free) heap, it should wait untill first thread will complete heap operation.
Then system releases ownership of the mutex, and second thread can have it.
All this takes extra time. And bassically, if you create heap in single-threaded process (i guess most asm-projects is single-threaded),
you should specify HEAP_NO_SERIALIZE. It speeds up the heap operations.
If you have only one thread, there is no reason to syncronyze it to whatever.

Hope it's clear now.

BTW, what reason for HEAP_GENERATE_EXCEPTIONS?
An exception is just another way for the system to notify your application about error (for example, out-of-memory).
If you have specifyed this flag you have to handle exceptions by yourself.
And i guess it's not what you want. In your case, IMHO, much simplier to allow the system do it for you.
This way you have only to check for returning NULL from HeapCreate/HeapAlloc.

...while it is "only allows one process to access the heap at a time"...)
Not process but thread. The process itself has no access to anything. It's only container for objects.
Posted on 2002-09-14 06:49:28 by Four-F
BTW, what reason for HEAP_GENERATE_EXCEPTIONS?

Well, it's pure laziness. At this stage in the project I just try to get the basic sceleton running, and I only use pre-decided conditions (thus user can't really do anything); so letting the SEH take care of some errors is a temporary solution, and it's far from perfect (or good)...

Not process but thread. The process itself has no access to anything. It's only container for objects.

I mean thread, wrote the wrong word.

"(I read the description as this 'to allow multithreading'" means: I read the text wrong... :)
Posted on 2002-09-14 08:19:31 by scientica
Here is a RadASM project using NMAKE:
Posted on 2002-09-14 09:12:35 by bitRAKE
:confused: :confused: :confused: !

How the HLL ( :rollwyes: ) is these .mak file structured? (no offense to the writer)
Ok, let me guess what happens (red text is my guess):

# objs needed to build the executable A comment

# This is the main project name: A comment
_MAIN_FILE_ = Rad-Modular some kind of definition

# Set-up Environment # Could also assume it's already been set? A comment

PATH = C:\Program Files\Microsoft Visual Studio.NET\Vc7\bin;$(PATH) adding more to the eviroment strings
LIB = C:\Program Files\Microsoft Visual Studio.NET\Vc7\lib;C:\RadASM\Lib;$(LIB) same as above
INCLUDE = C:\RadASM\Include\WinXP;C:\RadASM\Include;$(INCLUDE) same as above

LINK = LINK /nologo /SUBSYSTEM:WINDOWS /ENTRY:start /OUT:$(_MAIN_FILE_).exe setting up some sort of LINK textequ <"link /nologo ....">
AFLAGS = /c /coff /nologo same here



OBJS = $(_MAIN_FILE_).obj $(_MAIN_FILE_).res Private-A.obj Private-B.obj some strange definition

# Dependancies # A comment

$(_MAIN_FILE_).exe : $(OBJS) WTF happens here?
$(LINK) $(OBJS) kernel32.lib user32.lib what happens here


$(_MAIN_FILE_).obj : $(_MAIN_FILE_).asm $(_MAIN_FILE_).Inc Public.Inc Some label thingy?

# $(_MAIN_FILE_).res : ? # When should the resource file be rebuilt? What?

Private-A.obj : Private-A.Asm Public.Inc label thing?

Private-B.obj : Private-B.Asm Public.Inc same ??? as above

clean : some standard label?
del $(OBJS) dos command?
del $(_MAIN_FILE_).exe -- | | --
Posted on 2002-09-14 10:55:35 by scientica
scientica, good to see you understand it. :)
Did you google for NMAKE? ...or read any docs?

Private-A.obj : Private-A.Asm Public.Inc

These lines define dependancies. It says, "If either two files change then rebuild the target."

$(_MAIN_FILE_) is replaced by the equate name.

Also, by default NMAKE creates the first dependancy it finds.
$(_MAIN_FILE_).exe in this file.

Using this info you should be able to follow the dependancy chain:

$(_MAIN_FILE_).exe -->

$(_MAIN_FILE_).obj $(_MAIN_FILE_).res Private-A.obj Private-B.obj

--------- Private-A.obj --> Private-A.Asm Public.Inc

--------- Private-B.obj --> Private-B.Asm Public.Inc

Now NMAKE knows what is required to build each file. Internally NMAKE has the rules to know what to do with a ASM or OBJ file - the defaults are used. Here are default rules:
Microsoft (R) Program Maintenance Utility Version 7.00.9254

Copyright (C) Microsoft Corporation. All rights reserved.

INCLUDE =
_NMAKE_VER = 7.00.9254
MAKE = nmake
COBOL = cobol
BC = bc
CC = cl
MAKEFLAGS = {commandline}
AS = ml
RC = rc
PASCAL = pl
LIB =
CPP = cl
FOR = fl32
CXX = cl
MAKEDIR =

# INFERENCE RULES:
#
# .asm.exe: commands: $(AS) $(AFLAGS) $*.asm
# .asm.obj: commands: $(AS) $(AFLAGS) /c $*.asm
# .c.exe: commands: $(CC) $(CFLAGS) $<
# .c.obj: commands: $(CC) $(CFLAGS) /c $<
# .cpp.exe: commands: $(CPP) $(CPPFLAGS) $<
# .cpp.obj: commands: $(CPP) $(CPPFLAGS) /c $<
# .cxx.exe: commands: $(CXX) $(CXXFLAGS) $<
# .cxx.obj: commands: $(CXX) $(CXXFLAGS) /c $<
# .bas.obj: commands: $(BC) $(BFLAGS) $*.bas;
# .cbl.exe: commands: $(COBOL) $(COBFLAGS) $*.cbl, $*.exe;
# .cbl.obj: commands: $(COBOL) $(COBFLAGS) $*.cbl;
# .f.exe: commands: $(FOR) $(FFLAGS) $*.f
# .f.obj: commands: $(FOR) /c $(FFLAGS) $*.f
# .f90.exe: commands: $(FOR) $(FFLAGS) $*.f90
# .f90.obj: commands: $(FOR) /c $(FFLAGS) $*.f90
# .for.exe: commands: $(FOR) $(FFLAGS) $*.for
# .for.obj: commands: $(FOR) /c $(FFLAGS) $*.for
# .pas.exe: commands: $(PASCAL) $(PFLAGS) $*.pas
# .pas.obj: commands: $(PASCAL) /c $(PFLAGS) $*.pas
# .rc.res: commands: $(RC) $(RFLAGS) /r $*
#
# .SUFFIXES: .exe .obj .asm .c .cpp .cxx .bas .cbl .f .f90 .for .pas .res .rc
Posted on 2002-09-14 11:35:33 by bitRAKE