EmbeddedRelated.com
Forums
The 2026 Embedded Online Conference

Language feature selection

Started by Don Y March 5, 2017
On 3/18/2017 4:04 AM, Don Y wrote:
> On 3/18/2017 3:05 AM, Tauno Voipio wrote: >> Just get the book >> >> Andrew S. Tanenbaum, Operating Systems: Design and Implementation, >> >> read and understand it, then come back. > > AST doesn't address distributed OS's in that tome concentrating only > on a toy OS. Get his _Distributed Operating Systems_. Understand *it*. > Make sure you can understand why a distributed OS is a very different > animal from a monolithic one. Pay particular attention to the case > studies of Mach, Amoeba and Chorus and the tradeoffs made in their > *different* implementations. > > Then, go chase down the *technical* information on each of those. > Boykin et al. would be a good place for you to get some exposure to > what you could do with the original Mach. Amoeba will require a fair bit > more digging (no source code available). Then, you can look into the
Sorry, Amoeba *is* available; *Alpha* (Jensen et al.) isn't -- but has similarly applicable concepts (particularly capability handling). You'll need to understand both approaches, and their consequences, before you can appreciate how they can be leveraged for security and reliability (esp redundancy).
> Inferno docs to see how they handle location transparency and followup > issues addressed in their Grid implementation. From there, imagine how > you'd support resource migration in each of the above -- and how > you'd expose it to the developer. > > Finally, sort out how to extend all of these concepts to real-time > programming. > > [All this assumes you've already been through Organick, McKusick, etc.] > > Don't bother coming back -- been there, done that, T-shirt, etc. :> >
On Thu, 16 Mar 2017 17:23:11 -0700, Don Y
<blockedofcourse@foo.invalid> wrote:

>Hi George, > >On 3/15/2017 6:05 PM, George Neuner wrote: > >>> Assume applet, memory_manager_module, applet_parent. >>> >>> Applet_parent (for example) instantiates a memory object for applet. Part >>> of that requires binding parameters to that memory object (size, granularity, >>> allocation_policy, release_policy, etc.). Applet_parent need not persist >>> beyond this point (assume its job is done). >>> >>> Where do the bound parameters get stored? In the applet? In the memory >>> object? Obviously, can't be part of applet_parent because that won't >>> persist (unless you make other arrangements for it or portions of it). >>> >>> [I.e., applet_parent can't define an allocation handler in its body.] >>> >>> Now, migrate applet to another node. Another (shared) instance of >>> memory_manager_module likely already exists on that node. If the >>> allocation handler was a "stock" handler (contained in the >>> memory_manager_module), can you simply copy the state over to >>> the new node? >>> >>> What if the allocation handler was resident in some OTHER module >>> on the original node? Do you migrate that other module, as well? >>> Or, instantiate another copy if the module has outstanding references >>> on the first node?? >> >> For one "applet" (process / security context) to allocate memory on >> behalf of another, that memory has to be supplied by something that >> exists outside of either of them. > >Actually, the memory can exist anywhere: in some global space, in >the "allocating entity" or in the "client entity". As can the code >that does the actual allocating (at the behest of the allocator). > >[Consider client environment not supporting arbitrary pointers. >Unless something *gives* you a reference/handle to a piece of memory, >there's no way you can access its contents (short of an exploit). >E.g., no way you can go looking up/down the stack even though you >know there *is* a stack supporting the implementation language] > >> Thus the system memory manager can't be a dynamic "module" loaded >> locally into a process. Its *interface* could be, but not the manager >> itself. >> >> Leaving that aside. >> >> Ok, so you have a block of system memory, and you created one (or >> more) heaps having certain properties within the block - heaps which >> are "managed" locally in the process by code from a dynamic module. >> And now you want to rehost the process. > >Objects (heaps in this example) are managed by <something>. That >something may be the entity "owning" the object, a proxy or the >OS acting as the "proxy of last resort". > >The actions involved in management may reside in the OS, a service >(created by <something> -- including the client in question!) or the >client. At the direct or *implied* request of the client, etc. > >> 1) The obvious: store the heap properties together with the heap so >> that "copying" (serializing) the contents of the memory block to >> another host replicates the heap state for the equivalent "manager" >> module on that system. > >This potentially exposes those "trusted" parameters to abuse by >the entiti(es) having access to the underlying object. E.g., if client >can tweek the "heapsize" parameter stored there, then it can potentially >trick the "manager" on the remote system to instantiate a larger heap than >it was originally allowed to create (unless you rerun the "create_heap" >request as part of the migration effort) > >Likewise, if some of the "properties" reside *in* the client (e.g., >the algorithm by which allocations will be performed -- under the >supervision of some remote/system service that actually *does* them), >then you have to drag that/those things along with you. > >[Imagine these things reside in a *third* entity] > >> 2) Rehosting a running process necessarily requires checkpointing, >> copying or reconstructing its entire dynamic state: heaps, stacks, >> globals, loaded modules, kernel [meta]data, etc. - far more than one >> memory block. >> >> Every piece of distributed state must be identifiable as belonging to >> the process - regardless of what "module" may have created or is >> currently managing it. >> >> You have to copy all data belonging to the process, so having heap >> properties stored separately from the heap itself is not a problem. > >In my "portable" case, this is handled by moving the object handles. >The system can then opt to "optimize" execution by (later?) moving the >actual object instances (to minimize communication delays or take >better advantage of processing power on some particular node -- which >may differ from the source or destination nodes) > >But, you can (currently!) create "non-portable" objects. And, objects >that can't (easily) be shared. (e.g., for a "conventional" heap, you >can let the default policies available in a "heap manager" govern >the way the heap operates. *But*, you can't take advantage of any >"enhanced capabilities" in much the same way that you can't in a >more conventional process container, etc.) > >The problem with this (apparently arbitrary) distinction between >portable/shareable objects and "legacy" variety implementations >is that the developer has to explicitly decide what can be migrated, >shared, and how (because the developer has to take extra steps at >compile and link time to make those capabilities available). > >So, where these sorts of bindings get stored (and how they get >tracked) varies based on this "other" information that the developer >supplies. > >[You don't want to have to change the sources to support these >abilities as you want to be able to experiment with letting them migrate, >be shared, etc. without having to undertake a rewrite/refactoring. >And, I can't see an easy way for the build tools to determine that >without explicit directives from the developer (hence my related >comments in this thread)] > >> [Unless the systems involved do not have MMU/VMM such that the process >> address space can be faithfully reconstructed ... but if you really >> need to do it, it can be done using a software based virtual machine >> solution.] >> >>> Or, do you require declarations as to what *can* migrate and what >>> is bound in place? Then, contend with the consequences of >>> cascaded dependencies? >>> >>> The "consistent" solution is to make all of these first class >>> objects and let the OS manage them and their locations/instantiations. >>> But, that adds considerably to the cost of *using* them. >> >> Yes, that certainly is the ridiculous, overcompensating solution. >> >> The "consistent" solution is the one done already by any decent OS: >> keep a record of all the kernel structures and memory pages belonging >> to the process. >> >> Program objects then are just ordinary data in memory blocks "owned" >> by the process, or by the kernel on behalf of the process. > >But that ignores all of the "other" dependencies that can be in >play at any given time (i.e., my "solution" being these portable >handles that the OS tracks for the application/developer). So, ><something> knows that there is an aspect of the current applet's >instantiation that relies upon something else *or* that is relied >upon BY something else. > >[My approach lets the run-time know of these possible external >references by the presence of object handles held -- or exported -- by >the applet in question. *Absent* these, the task is just a block of >memory and "processor state" that can be copied anywhere and "resumed".] > >> Ensuring that a rehosted program will work is another matter. But as >> I understand (???) your system, there is location transparent naming >> and equivalence[*] hosts will expose the same set of service APIs. >> >> [*] capable of running the same applications. >> >>> Its a lot easier to deal with implementations where "everything" is >>> a cohesive "blob" instead of being able to slice-and-dice it at >>> run-time and redistribute it based on evolving workloads, resources, >>> etc. >> >> You can somewhat mitigate the problem by making large allocations >> piece wise: abusing VMM to make them appear address contiguous. >> >> E.g., if a process asks for 100MB, reserve the address space but >> instantiate just a few megabytes at a time, on demand as the process >> touches unbacked addresses. >> >> [Because (I assume) you don't want to overcommit memory, you need to >> reserve requested address space both locally in the process, and >> globally so that other processes can't accidentally grab it.] > >Resource constraints vary with the resource and the consumer/provider. >You can overcommit many resources because many "jobs" don't exploit >their worst-case resource needs. > >But, you do so at the risk of delaying the availability of those resources >to the job in question. Or, some other job interested in those resources. > >[E.g., if your job is diarising a previously recorded telephone conversation, >it can *probably* afford to block waiting on memory that it needs to complete >that task -- perhaps even indefinitely! It shouldn't be prevented from >starting just because the MAX memory that MIGHT be required isn't presently >available. Nor should all of that memory be wired down for its benefit >without knowing that it *will* need it -- or, when!] > >> You need to reconstruct the address space on the new host, but you >> need only copy as much physical memory as the process is actually >> using. >> >> Aside: one of the nice features of "moving" GC is that it compacts >> live data into a (usually) smaller address range. You don't want to >> have to copy a large block to get at a much smaller volume of data >> contained within it. > >But you need a way of tying a "handle" to the data involved -- and, >later, resolving that reference. > >> There are a number of tricks that involve using VMM to implement GC. >> You can't completely avoid data copying if you want to compact the >> live data, but using VMM techniques together with clustered BiBoP >> allocation, you can reduce the amount of copying to bare minimum. >> >> It also is possible to use VMM and just the tracing step of GC to >> identify the actual set of pages containing live data ... you don't >> need to copy any more than that even if the process has much more >> memory instantiated. >> >> And regardless of whether you (would want to) use GC in normal >> operation, if it is supported by the language/runtime, a compacting >> collection executed before rehosting a process would minimize both >> what needs to be copied and the physical memory that must be >> instantiated on the target. >> >>> Last 25# of oranges... yippee! >> >> 10 inches of snow, followed by sleet, followed by freezing temps. The > >Yeah, caught a glimpse of that on the national news... > >> crust is ~3/4 of an inch thick - my 185 lbs can walk on top of it. Had >> to use the heavy coal shovel to break it up so it could be removed. > >90's, here. I think 95 expected this weekend. Being outdoors is a >chore as it's either too warm during the daylight hours *or* the air >too "smelly" (everything is in bloom) in the cooler hours when the >breeze has died down. > >I'd (personally) appreciate a cold spell (but not *now* as the new >crop of fruit is setting in place) to slow the growth process. I >suspect it will be a bad year for insects! > >[Normally, we don't see 95 until May; and 90 until mid-April]
I am not sure where you did move the goal posts this time, but at least the VAX/VMS VAXcluster addressed some of these issues in the 1980s. Switching processes between (cabinet size) CPUs was routine via a shared (redundant) disk pool (checkpointing and virtual memory page faulting). These days the disk pool could be part of the L3 (or L4) cache hierarchy.
The 2026 Embedded Online Conference