English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 12 March 2021, 19:05   #21
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Quote:
Originally Posted by nyteshade View Post
Do people here not use CreatePool(), AllocPooled() and DeletePool?
Yeah but only on Kickstart 3.1+. 3.0 was buggy and 2.x added a linker library not needed on KS3.
Samurai_Crow is offline  
Old 12 March 2021, 19:06   #22
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Quote:
Originally Posted by Ernst Blofeld View Post
Is this available on Kickstart 1.2?
Neither is AllocVec/FreeVec.
Samurai_Crow is offline  
Old 12 March 2021, 19:12   #23
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by Samurai_Crow View Post
Neither is AllocVec/FreeVec.
Well, true, but easily replicated with normal malloc calls. The pooled stuff takes more than 2 lines of code.

Edit: And considering your posts above, why do you even think this is worth arguing about?
Ernst Blofeld is offline  
Old 12 March 2021, 19:38   #24
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Quote:
Originally Posted by Ernst Blofeld View Post
Edit: And considering your posts above, why do you even think this is worth arguing about?
I want to develop in C++11 or newer but the fully retro crowd refuses to upgrade to the latest Kickstarts. This means I have to keep track of what routines I can and can't use in my code. What a PITA!
Samurai_Crow is offline  
Old 12 March 2021, 19:44   #25
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by Samurai_Crow View Post
retro
adjective Informal: of or designating the style of an earlier time
Ernst Blofeld is offline  
Old 12 March 2021, 19:59   #26
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Quote:
Originally Posted by Emufr3ak View Post
I can define classes and access them. As soon as I use the new operator I get linker errors (undefined symbol).

You can simply provide your own "operator new()". Actually, you need to create two operator new, the array version and the scalar version, and the corresponding operator delete, also both versions. You need to throw "bad_alloc" then yourself if the allocation fails.
Thomas Richter is offline  
Old 21 April 2022, 19:59   #27
deimos
It's coming back!
 
deimos's Avatar
 
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
Quote:
Originally Posted by Thomas Richter View Post
You can simply provide your own "operator new()". Actually, you need to create two operator new, the array version and the scalar version, and the corresponding operator delete, also both versions. You need to throw "bad_alloc" then yourself if the allocation fails.
I've implement this, but without being sure exactly what is correct, could someone please sense check this?

Code:
#include <proto/exec.h>

namespace std {
    using size_t = ULONG;
}

using namespace std;

void * operator new (size_t sz) {
    void * memoryBlock = (void *) AllocMem((ULONG) sz + 4, MEMF_ANY);
    *((ULONG *) memoryBlock) = (ULONG) sz;
    return (void *) (((BYTE *) memoryBlock) + 4);
}

void * operator new [] (size_t sz) {
    void * memoryBlock = (void *) AllocMem((ULONG) sz + 4, MEMF_ANY);
    *((ULONG *) memoryBlock) = (ULONG) sz;
    return (void *) (((BYTE *) memoryBlock) + 4);
}

void operator delete (void * ptr) {
    void * memoryBlock = (void *) ((((BYTE *) ptr) - 4));
    ULONG byteSize = *((ULONG *) memoryBlock);
    FreeMem(memoryBlock, byteSize);
}

void operator delete (void * ptr, size_t sz) {
    void * memoryBlock = (void *) ((((BYTE *) ptr) - 4));
    ULONG byteSize = *((ULONG *) memoryBlock);
    FreeMem(memoryBlock, byteSize);
}

void operator delete [] (void * ptr) {
    void * memoryBlock = (void *) ((((BYTE *) ptr) - 4));
    ULONG byteSize = *((ULONG *) memoryBlock);
    FreeMem(memoryBlock, byteSize);
}

void operator delete [] (void * ptr, size_t sz) {
    void * memoryBlock = (void *) ((((BYTE *) ptr) - 4));
    ULONG byteSize = *((ULONG *) memoryBlock);
    FreeMem(memoryBlock, byteSize);
}

// suppress error squiggle for fake size_t
#ifdef __INTELLISENSE__
#pragma diag_suppress 351
#endif
It works, apparently, but I don't understand why so many functions are needed, for a start.

Also, are there any opportunities to be smart, i.e. could I make new operators for things that need to go into chip memory?

Last edited by deimos; 21 April 2022 at 20:13.
deimos is offline  
Old 21 April 2022, 21:13   #28
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,098
Quote:
Originally Posted by deimos View Post
It works, apparently, but I don't understand why so many functions are needed, for a start.
Usually they'd be provided by the standard library and you would never notice. The "standard" use case for implementing these functions yourself is to track allocations and detect mismatches in the use of "array new" vs. plain "delete" (i.e. Object* o = new Object[10] .. delete o). Note that you aren't properly dealing with allocation failures.

Quote:
Originally Posted by deimos View Post
Also, are there any opportunities to be smart, i.e. could I make new operators for things that need to go into chip memory?
That's possible, but I'd advise against it.
paraj is offline  
Old 21 April 2022, 21:20   #29
deimos
It's coming back!
 
deimos's Avatar
 
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
I may have expressed myself poorly there, I meant that I didn't understand why more than one new and one delete was needed - I just kept adding them until the linker stopped complaining.

The special use case here is that there is no standard library supplied - I don't even get a definition of size_t.

Exceptions aren't enabled, so I can't handle a failure that way, but yes, maybe I should at least log it and call dos.library/Exit.
deimos is offline  
Old 21 April 2022, 21:40   #30
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,098
Quote:
Originally Posted by deimos View Post
I may have expressed myself poorly there, I meant that I didn't understand why more than one new and one delete was needed - I just kept adding them until the linker stopped complaining.The special use case here is that there is no standard library supplied - I don't even get a definition of size_t.
I probably wasn't too clear either, but the compiler will emit calls to all of the functions (or at least reference them) to support the standard use case even if you don't care about them.
Quote:
Originally Posted by deimos View Post
Exceptions aren't enabled, so I can't handle a failure that way, but yes, maybe I should at least log it and call dos.library/Exit.
Exiting on failure seems fine, but depending on what you're doing you may want to do proper clean-up first.
paraj is offline  
Old 22 April 2022, 18:39   #31
pink^abyss
Registered User
 
Join Date: Aug 2018
Location: Untergrund/Germany
Posts: 408
Quote:
Originally Posted by Emufr3ak View Post
Thank Ernst. This definitely pointed me in the right Direction. It's possible to implement new operators for new and delete. This did the trick.
To have more control and introspection I can recommend using Tiny Alloc
as a generic allocator (https://github.com/thi-ng/tinyalloc).

I used it on an Amiga OCS C++ game project. I extended it to support multiple heaps and memory tracking to avoid leaks. Let me know if you need the sources.
pink^abyss is offline  
Old 22 April 2022, 20:13   #32
deimos
It's coming back!
 
deimos's Avatar
 
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
Quote:
Originally Posted by pink^abyss View Post
To have more control and introspection I can recommend using Tiny Alloc
as a generic allocator (https://github.com/thi-ng/tinyalloc).

I used it on an Amiga OCS C++ game project. I extended it to support multiple heaps and memory tracking to avoid leaks. Let me know if you need the sources.
I would like to know more, if you can explain it using small words. This would be a replacement for AllocMem / FreeMem, right? but we'd still need our own new and free operators?
deimos is offline  
Old 23 April 2022, 13:17   #33
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Ernst Blofeld View Post
Is this available on Kickstart 1.2?
Yes, but "some assembly required"...

There are Kickstart 1.x/2.x compatible functions provided in the amiga.lib V39/V40 which go by the names of LibCreatePool/LibDeletePool/LibAllocPooled/LibFreePooled. They are declared in the "clib/alib_protos.h" header file. If you can make use of them, avoid amiga.lib V39 because of a bug eventually fixed in amiga.lib V40.

These Kickstart 1.x/2.x compatible functions will invoke their exec.library V39/V40 counterparts if running on Kickstart 3.0 and beyond rather than doing their own thing.

My own clib2 runtime library for GCC features 'C' implementations of LibCreatePool/LibDeletePool/LibAllocPooled/LibFreePooled in case these make more sense for you.
Olaf Barthel is offline  
Old 23 April 2022, 13:24   #34
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Also, are there any opportunities to be smart, i.e. could I make new operators for things that need to go into chip memory?
I would recommend to call the operating system functions as needed and keep track of what you allocated, then free it later. If this works for you, then maybe it would be worth investing into a more general mechanism for allocating and keeping track of memory with specific requirements (e.g. must be drawn from chip memory) and options (e.g. allocated memory contents will be set to zero).

Big pitfall when doing your own memory management based upon what AllocMem/FreeMem deliver: check if the size of the allocation is > 0. If not, return NULL. Your current implementation is perfectly fine with the size being 0, for which AllocMem(size+4, ...) will of course succeed. But this is not what the new operator should deliver.

Beyond that, you should keep track of which allocations have been made so far, or otherwise every new will have to be matched with a delete before the program may exit without leaking memory.
Olaf Barthel is offline  
Old 23 April 2022, 23:11   #35
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Quote:
Originally Posted by deimos View Post
I've implement this, but without being sure exactly what is correct, could someone please sense check this?
Essentially, yes, though I would use AllocVec() to begin with so you don't need to store the size away. Also, please throw bad_alloc() in case you could not get the memory.


Quote:
Originally Posted by deimos View Post

It works, apparently, but I don't understand why so many functions are needed, for a start.
You need separate operators for arrays than for scalars because the compiler also needs to store away the number of objects in the array to call the destructors of all the objects within the array, so you need two pairs. You do not need to provide the operator delete with size argument, it is an extra service of the compiler that it can supply the size (though it does not work reliable in some older versions of gcc).




Quote:
Originally Posted by deimos View Post

Also, are there any opportunities to be smart, i.e. could I make new operators for things that need to go into chip memory?
In principle yes, you can "misuse" the placement new operator ("new with argument") to provide also arguments, though you need a corresponding placement delete. The details when this is called are a bit delicate, and may not correspond well to your intuition, but for details, see the Stroustrup book.


Essentally, placement operator delete is only called if placement operator-new fails in the constructor, otherwise the regular operator-delete is called.


I personally prefer a somewhat different approach and avoid overloading the global operators because it typically means "trouble" as you (under the hood) also exchange the operator-new for everything that is linked to your file, sometimes with "surprising" side effects. Instead, it is better to have an object that provides its own operator new/delete pairs, and then use a coding guideline that requires that all your objects derivate from this object. This way, you do not create unforeseen side effects if you link with code from some other project.
Thomas Richter is offline  
Old 26 April 2022, 08:14   #36
pink^abyss
Registered User
 
Join Date: Aug 2018
Location: Untergrund/Germany
Posts: 408
Quote:
Originally Posted by deimos View Post
I would like to know more, if you can explain it using small words. This would be a replacement for AllocMem / FreeMem, right? but we'd still need our own new and free operators?

In my games I take all the memory I need on startup. I use the system routines to allocate two blocks, one for chipmem and one for other mem. Then I use TinyAlloc to manage this memory. If you want to use new/delete then you need own operators.
pink^abyss is offline  
Old 16 June 2023, 05:20   #37
Tom_Goblins
Registered User
 
Join Date: Dec 2018
Location: Seattle
Posts: 13
I went down all that pain. I started using Bebbo GCC with this one I don't link the stdlibc++ but I use the includes and replaced all those functions while using bebbo I can call malloc() and free(). Even I use hash table why not! in debug to keep track of memory leaks. It is good to have the stl around if you need something for quick prototype or convenience.

I do compile also for the vscode extension, but it requires a bit more of trickery here and there and define some extra functions but it works with no problem. It would be fantastic if this extension could support a bit more C++. STL as a whole is a bit overkill for amiga but using it on some specific locations is really useful. I modified EASTL for amiga as the vscode extension tolerates that better .

That being said, I follow similar pattern I do allocate things at once and I do not dynamically allocate anything from there.

@Pink I would be interested on your modifications for tiny alloc if you want to share. thanks in advance!.
Tom_Goblins is offline  
Old 08 August 2023, 00:05   #38
Tom_Goblins
Registered User
 
Join Date: Dec 2018
Location: Seattle
Posts: 13
Knightlore

Here is one game I did recently using all modern C++ with STL for A500. It compiles with both Bebbo and Amiga VSCode extension.

[ Show youtube player ]
Tom_Goblins is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
amiga-gcc minimal output Fook42 Coders. C/C++ 17 02 May 2019 09:49
Amiga GCC 6.2 developer guide appreciated asymetrix Coders. C/C++ 19 11 October 2018 23:58
Req: gcc crosscompiler with amiga hunk support emufan Coders. C/C++ 5 02 October 2017 01:51
Amiga GCC Where to find it? _ThEcRoW request.Apps 10 02 March 2006 00:44
Amiga GCC Where can i find? _ThEcRoW request.Apps 1 22 October 2005 18:17

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 20:10.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13342 seconds with 13 queries