mishkin@EDDIE.MIT.EDU@apollo.UUCP (12/04/86)
I have a program which consumes massive amounts of dynamic memory. The inevitable problem is that the disk fills up and the program stops. It seems the new and rws_$alloc procedures don't detect that the disk is full. The fault occurs when the pointer is dereferenced. I have been able to trap this fault, but I haven't been able to do anything about it. When I dispose of some memory and return from the fault handler with the value pfm_$return_to_faulting_code the process dies without a clue as to what happened. I'm afraid there's no very nice way to deal with this problem. The problem is equivalent to the "out of swap space" problem on other operating systems. On the Apollo however, the disk(s) are not divided into swap areas and filesystem areas. There are only filesystem areas (and generally only one of them per disk). The reason "rws_$alloc" doesn't return an error is because it is layered on top of the virtual memory mapping primitives. When one maps some non-yet-existing pages of a file (e.g. pages past the current "EOF"), the pages are not actually allocated on the disk until the virtual addresses corresponding to the pages are accessed. "rws_$alloc" does not access those addresses, so the client of "rws_$alloc" (i.e. the code that uses the returned pointer) is the first acccessor (and hence the one that causes the disk-full fault). The reason catching the fault didn't work is because the disk-full fault is "not continuable". At some future release, this problem will probably be dealt with by making RWS ensure that the disk pages are there to back the virtual memory it's allocating. Until then, you can work around the problem by doing something like: char *my_alloc(len) int len; { char *p, *q; status_$t st, fst; pfm_$cleanup_rec crec; /* * Allocate the storage. */ p = rws_$alloc_heap_pool(rws_$std_pool, len); if (p == 0) return (p); /* * Loop over the storage, touching it to cause the disk pages to be * allocated. Note we set up a cleanup handler to catch disk-full * faults. */ fst = pfm_$cleanup(crec); if (fst.all != pfm_$cleanup_set) { rws_$release_heap_pool(p, rws_$std_pool, st); pfm_$enable(); return ((char *) 0); } for (q = p; q < p + len; q += 1024) *q = 0; pfm_$rls_cleanup(crec, st); return (p); } Note that, unfortunately, the disk space backing RWS space is not freed until the program returns. I.e. calling "rws_$release_heap..." will NOT immediately result in disk space being made available. However, it will make the RWS space available for other uses. This scheme also should keep the process from dying mysteriously. We know this is a problem. -- Nat Mishkin Apollo Computer Inc. mishkin@apollo.uucp -------