The daemon could also search actively for a library allowing the user to specify one if it can't be found. Paths like PROGDIR: should be searched automatically.
If the lib can't be found, DOS_OpenLibrary() must create a message port and a message, put the port in the reply-to field of the message as well as the name and min-version of the lib and then send the message to the lddaemon and wait for the reply.
Open questions: Will this interfere with the way Exec handles libraries now (eg. single threaded libInit()) ? Can this introduce deadlocks in the locking of the exec library list ? What happens if libClose() calls libExpunge() ?
The objects should contain the data in a raw format so that the methods can easily operate on it. One should be able to stream data in and out of the objects. One could have separate "converter objects" that can convert from a data format (eg. GIF->internal raw image format and back eg. raw->GIF.) So when you want to put a GIF file into an image object the system will automatically search for installed gif->internal raw converters and convert the GIF into a stream of raw image data passed to the image object.
These data objects should of course have methods like Show() and Edit(). Edit() could invoke your favourite texteditor/paintprogram/drawprogram/etc depending on the object type. (text/image/structured drawing).
Now, should these objects be able to show themselves, like the old datatypes ? Well, IMO they should not be bound to a single operating system/GUI system, but they could maybe show themselves through some RTG system (?). But the viewer could also stream out the data from the object to show. When the object's data has changed, the viewer could be notified and where in the stream the "damaged" data is. (If a text viewer GUI views the first 100 lines of a 100000 line text data object, and the last 100 lines are changed, it wouldn't need to rerender).
As mentioned earlier one should be able to use this system on different OSes, and it should maybe also be possible to invoke methods on them over a network or even move the objects in a network (using CORBA ?). This way a heavy operation on the data object can be done on a faster machine while you are controlling it from a slower machine.
By keeping functionality into small components, 3rd party programmers can easily write freeware additional functionality. (One can add methods operating on the data one at a time.) It will provide very much reuse of code. (Just look around on Aminet: There are whole bunch of different image processing programs that implement the same functionality. This should really only have to be written once). If the system can work on other platforms too, we get even more developers that can support it.
I believe that if some system should have any chance at all of taking some market share from M$ it a) has to be free. b) must be available on as many platforms as possible. c) must consist of tiny components that can be added at run-time.=>This way it'll be easier for developers to support it.
A select/asyncio handler (AsyncIO.hidd ?) which handles allocation of buffers and IO on multiple handlers could allocate buffers, do multiple reads on behalf of a process and signal the process when input is available. The same would happen for write operations (writing would block when the select handler has queued a maximum of bytes or buffers for a single process).
A process that wants to exit could just close the select handler and leave it to the handler to deallocate the buffers when they are returned one day ... Under AROS the handler would be able to use AbortPkt() and under AmigaOS it would be able to use it if the patch is installed and the underlying handler accepts the packet type ACTION_ABORT.
The idea reminds me a bit of Unix STREAMS or NT device drivers: both pass packets through several layers of device abstractions. UnixIO could be one layer below the select handler and would translate it to a real select() because the buffer mechanism of the select handler is part of the Unix kernel anyway; so a write would block when the kernel buffers are full, as usual.
This memory is allocated by special functions. It doesn't appear in the "memory used" list but is added to the amount of free memory. Besides allocation and freeing there are two special cases. The simple one is that some other application needs the RAM, so parts of the cache have to be purged. The other one is to avoid memory fragmentation. It's not possible or useful to use all the free memory for caching. So the cache should always be one large block divided up in several smaller chunks. If an application needs memory, parts of the cache have to be freed *or* they have to be copied in unused chunks (eg. it's still faster to copy 512 bytes than to read them back from HD or a printer spooler should not throw the spooled data away).
[Aaron Digulla: This is dangerous; it uses a lot of memory, adds many IDCMP event loops and the same effect can be achieved when using clip regions; all we have to do is to make the gadgets public, which render a window, plus maybe a BOOPSI subwindow class which installs a clip region in another window.]
In this system, each process has its own memory map, but the actual mapping is still global (eg, there's just one memory space). Your process can see the rest of the world as read-only. Functions like AllocMem() transparently work from local memory pools attached to your process, so things stay nicely page-aligned. This has the secondary effect of making AllocMem() faster than it is today, since you only have to involve Exec proper (locking the system up to keep things atomic) every so often, not at every AllocMem().
I would make the extension to this that memory contexts become first-class Exec objects. The System context would be the "root", with read/write access as we have today. Device drivers that need the direct access to hardware, or the performance of using references rather than copies, could be started on this context. You could build alternate contexts, such as the read-only underlay, as mentioned, or even fully private memory spaces, as in UNIX. Obviously this is for new code, and Exec would need to add/enhance functions for sending messages, copying, etc. between memory spaces. But since you're not expecting any old code to run in a fully separate space, some of today's bad habits wouldn't really be an issue.
While doing this, we could also add methods to uninstall an installed package. By Aaron Digulla: There should be a tool to create a kernel which can be put into a Flash ROM or EEPROM or a boot file. The tool should be able to fix all absolute addresses in the kernel, it should be able to create the resident tags or a simple file system which allows the boot loader to find, load and init all parts it needs.
The main reasons for this are: When you add a new driver (eg. a harddisk controller), you don't want to have to install a C compiler just to be able to boot from it. The ordinary user just wants to call a "install driver" tool which does all the work without him worrying. Also to reduce similar code, the boot loader will probably use the same code to load drivers as will the OS. So the "file system" which is visible to the boot loader must be similar to what the OS sees. This becomes more important if some driver in the ROM is not loaded/inited during booting. Then the OS will use its normal ways to search for the driver and at this time, the driver must be visible by some file system-like means or the searching for it will fail.
If you have comments or suggestions, email me at digulla@aros.fh-konstanz.de. 24. Jul 1999