wyatt@cfa.harvard.EDU (Bill Wyatt) (06/28/87)
I have recently been using Ultrix 1.2 shared memory features, and I've come across a bug or misfeature that I'd like comments on. I've got a set of programs running asynchronously that pass data (usually in only one direction) about status, etc. While this could have, in most cases, been done with writes on sockets, etc., I decided a cleaner and more efficient implementation would be to use Ultrix's Sys V shared memory compatibility features. All programs agree on a unique identifier, they link in the shared memory segment, and you're set. Except, malloc() seems to break (sometimes). I turns out that the shared memory attach function selects a region of memory 32K above the current data break, and if you want to malloc more memory, you're out of luck. I've tried attaching to a specific address (on a page boundary), and it works, but malloc is still broken. I've tried issuing sbrk() calls explicitly after the shared memory attach, but it fails too. Looking at the <sys/shm.h> file shows a structure that gives information on the defaults such as how high above the data break to put the first shared memory segment, but there is no (documented) system call to read that information, much less change it! So, while I can work around the problem (detaching memory, malloc() what I need, re-attaching, blech!), that's not always going to be possible. I probably could specify an address way above the break, but that's not solving the fundamental problem, just putting the reckoning off a bit. Malloc and shared memory in Ultrix 1.2 seem to be incompatible. Is this true, or am I missing some better way of handling their interactions? Any comments appreciated. -- Bill UUCP: {seismo|ihnp4}!harvard!cfa!wyatt Wyatt ARPA: wyatt@cfa.harvard.edu (or) wyatt%cfa@harvard.harvard.edu BITNET: wyatt@cfa2 SPAN: 17410::wyatt (this will ukuku
dgg@ci-dandelion.UUCP (Dave Grubbs) (06/29/87)
Bill Wyatt @ cfa.harvard.edu writes: > I have recently been using Ultrix 1.2 shared memory features, and I've > come across a bug or misfeature that I'd like comments on. and goes on to describe the "32K" gap between Ultrix 1.2 data and shared memory spaces. > the Malloc and shared memory in Ultrix 1.2 seem to be incompatible. Is this > true, or am I missing some better way of handling their interactions? > Any comments appreciated. Here at Cognition, Inc., I spent many months last year correcting the shared memory support in Ultrix 1.2. I believe we have the only Ultrix 1.2 kernel in the world which supports (almost) unlimited shared data segments. Our product routinely uses multiple 10 Meg (yes, Megabytes) shared data segments. Ultrix 1.2 (and Ultrix 2.0, without reconfiguration) allows only 128K segments. There were on the order of 25 distinct corrections. In each case my contact at DEC either absorbed the change or discussed a superior implementation already developed at DEC for inclusion in Ultrix 2.0. We just got 2.0 and it seems to work. (We will find out for sure during product testing.) Now for the problem. The first Ultrix implementation of shared memory was an attempt to copy the concept from the shared text implementation. They made a large number of poor assumptions based on the relative simplicity of the shared text implementation. There are many differences. For example: Shared text: Shared data: - Read-Only - Read-Write - One per process - Many per process - Starts at fixed address (0) - Table of attach points - System "owned" - Privately "owned" - Tied to a process - Independent of any process - Attached automatically - Attached by user choice - Page table is part of initial - Page table is created by allocation. "expanding" the existing one. - No gap in page table. - "Float"s between data and stack. The major hassle is that the VAX's page tables are fixed linear arrays. When you attach a shared segment, all page tables between the current top of data and the attach point must be allocated. Hence a small "gap" (i.e. 32K) to limit the wasted page table space. malloc() and sbrk() DO work. They "fill in" the gap between the current "brk" (top of data) and the bottom of the first attached shared segment. If you need lots of allocated space, the only solution is to attach the shared segment high enough to accomodate any data allocation you want to do. Now if the VAX had the ability to handle gaps in its page tables (like an Apollo or IBM PC/RT) we could attach shared segments off in outer space and not have to worry about it. Beware of kernel crashes due to shared memory. In the standard Ultrix 1.2 implementation shared memory can crash the kernel in a thousand ways, most of which are "stress" situations, with lots of paging and swapping. Here are two simple ways to crash it: 1) Carefully sbrk all the data up to the shared segment attach point. Force the last page of user data and the first page of shared data page out (Start up a lot of processes). Then force it to page back in. You will either get a page of random data in the shared data area or an Ultrix crash. 2) Attach it into the middle of your process. address = sbrk(Any amount); shmid = shmget (12345, 10000, IPC_CREAT); shmat (shmid, address, 0); Ultrix should crash. This is also easy to avoid. David G. Grubbs Cognition Inc. 900 Tech Park Drive uucp: ...!{mit-eddie,talcott,necntc}!ci-dandelion!dgg Billerica, MA 01821 arpa: dgg@athena.mit.edu, dgg@ci-dandelion.ci.com (617) 667-4800
henry@utzoo.UUCP (Henry Spencer) (07/03/87)
> Now if the VAX had the ability to handle gaps in its page tables (like > an Apollo or IBM PC/RT) we could attach shared segments off in outer > space and not have to worry about it. Note that since the VAX user page tables are in kernel *virtual* space, the VAX can in fact have gaps in its page tables if you manage the kernel page table cleverly. (Always looked that way to me, anyway -- never tried it personally.) -- Mars must wait -- we have un- Henry Spencer @ U of Toronto Zoology finished business on the Moon. {allegra,ihnp4,decvax,pyramid}!utzoo!henry