dschmenk / PLASMA

Proto Language AsSeMbler for All (formerly Apple)
MIT License
194 stars 26 forks source link

What should happen if fileio:iobufalloc() is called more than once? #60

Open ZornsLemma opened 4 years ago

ZornsLemma commented 4 years ago

I may be losing the plot but I hope what I'm about to write makes sense... Apologies if I've misinterpreted how the logic works!

I'm looking at the Apple II code in fileio.pla, i.e. the a2iobufs() function.

To start with, one iobuf is allocated by default. If we call fileio:iobufalloc(2), a2iobufs() will subtract one from the argument to allow for the system I/O buffer and will allocate one more buffer (i==1), giving us two in total. All good.

Now suppose we call fileio:iobufalloc(2) again. a2iobufs() will subtract one from the argument to allow for the system I/O buffer. The 'for i=1 to MAX_IOBUFS-1' loop will then see that buffer 1 is already allocated, and because 'iobufs--' is inside the 'if not iobuf_addr[i]' block it won't execute, so that buffer doesn't count towards the 2 requested. We'll therefore loop round and allocate another buffer (i==2) before finishing. This leaves us with 3 buffers allocated. This seems odd; I would expect the second call to fileio:iobufalloc(2) to either be a no-op or to allocate a further two buffers for a total of four.

I don't think this is a big deal and I doubt most programs will try to call this more than once, but I'm working on my Acorn implementation of this so I thought I'd ask.

I think ideally fileio:iobufalloc(n) should allocate buffers if necessary so we have at least n buffers, and do nothing if we already have >=n buffers. (Assuming n!=0, of course, which would free buffers as it currently does.) My justification for this behaviour is a hypothetical situation where utility module A needs three buffers and utility module B needs two buffers. A would probably call fileio:iobufalloc(3) and B would probably call fileio:iobufalloc(2) in their INIT code, and I think we should end up with three buffers allocated in total, enough to satisfy either (as long as they don't need their buffers simultaneously).