5

When I run compile this code with SDCC 3.1.0, and run it on an Amstrad CPC 464 (under emulation, with WinCPC 0.9.26 running on Wine):

void _test_malloc()
{
  long idx = 0;
  while (1)
    {
      if (malloc(5))
    {
      printf("%ld\r\n", ++idx);
    }
      else
    {
      printf("done");
      break;
    }
  }
}

... it consistently taps out at 92 malloc()s. I make that 460 bytes, which leads me to a couple of questions:

  • What is malloc() doing on this system? I was sort of hoping for an order of magnitude more storage even on a 64kB system

  • The behaviour is consistent on 64kB systems and 128kB systems; do I have to perform some sort of magic to access the additional memory, like manual bank switching?

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
Duncan Bayne
  • 3,870
  • 4
  • 39
  • 64
  • Why the 5-byte increments? What happens when you allocate larger chunks (just being curious)? Other question: How much stack space are you allowed to take? – meaning-matters Jun 29 '13 at 14:16

2 Answers2

6

In fact, as Duncan Bayne says, there is a very narrow heap space in the default memory manager that SDCC implements for Z80.

However, before trying to modify SDCC's heap, you should consider if you actually need dynamic memory on an Amstrad CPC. Generally, there is no point on using dynamic memory when you run a stand-alone application, which owns the entire hardware. You can test and know how much memory you have, and you can directly write to memory wherever you wanted. There is no memory protection, and no other applications running on background.

Therefore, is much preferable for you to design your own memory map (where you want your data to be and how much space to use) and then directly manage the memory. Moreover, code optimization is much important in this machine, and manually managing memory is extremelly relevant for optimization.

If your code is running directly in the Amstrad CPC (i.e. not using a modern OS like Symbos), you have to manually deal with bank switching to access memory. Z80 CPU has a 16-bits bus, which can only address 64KB of memory without bank switching.

ronaldo
  • 455
  • 3
  • 9
  • The drawback of static memory allocation here is that you're effectively forced to pay for worst-case limits for all buffers even if your application isn't ever going to fill them all simultaneously. Granted on systems like these the costs are also very high but certainly I wouldn't dismiss dynamic allocation out-of-hand (though generic `malloc` certainly is out.) – doynax May 29 '15 at 18:05
  • In fact, if you think of it, that's not exactly a drawback. If you wanted your application to manage X data, you would need that memory available or won't be able to do that. If you do it dynamically, you need to allocate that space for the heap too. – ronaldo May 30 '15 at 09:52
  • (continuing...) From my point of view, it is generally more interesting to design your own memory pool, to serve your own distinct purposes and manage it directly. Worst-case limits must always be considered, especially with limited resources. Anyway, my general advice is to consider approaches beforehand and not resort to default. The rest is just my personal view. – ronaldo May 30 '15 at 09:58
  • 1
    The point I was trying to make is that you might be writing (say) a CPC game for which level one needs lots of animation but has a small map area whereas level two has opposite requirements. In such a case a dynamic split between the two resource types, whether provided by `malloc` or more likely a custom allocation strategy, improves the overall memory utilization. Naturally the amount of _care_ needed to be taken is proportional to the tightness of the memory budget but then so are the potential benefits of a flexible approach. – doynax May 30 '15 at 13:58
  • Then, I totally agree with you. I think we were talking about the same, but simply had a different prespective regarding the word "dynamic" :). – ronaldo May 30 '15 at 15:26
4

The answer is that, on Z80 systems, heap size is hard-coded to 1kB. Maarten Brock answered this on the sdcc-user mailing list:

Hello Duncan,

You have to create the heap yourself if the standard 1kB is not enough. Copy heap.s into your project dir and modify it to create your preferred size. Then assemble it and link with your project.

Unlike the mcs51 heap which is defined in _heap.c this is not documented for Z80 in the manual. Feel free to request a documentation update or merge of _heap.c and heap.s in the tracker system.

Maarten

Duncan Bayne
  • 3,870
  • 4
  • 39
  • 64