Date: 15 Jan 1998 12:32 EST From: "Andrew Atrens" <atrens@nortel.ca> To: joelh@gnu.org Cc: tlambert@primenet.com, chrisy@flix.net, freebsd-hackers@FreeBSD.ORG Subject: Re: sharable static arrays? Message-ID: <199801151826.KAA18851@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
In message "sharable static arrays?", joelh@gnu.org writes: > > > OK. Sean was wrong and I was wrong. > > Not wrong, if I understand properly, you just correctly answered a > different question than what I meant to ask. > > > What you want is already in there. All original vnode data is > > shared between all processes. This includes static data. The > > program txt (executable code) is read-only. Data is read/write, but > > is marked copy-on-write. You do not take memory space for > > additional instances of the program, *unless* you write the data. > > If you do, it's copied. A page at a time. Uninitialized and > > allocated data are BSS data. This is allocated per process. > > So, let me make sure I've got this straight: > > int g_uninit; /* Global uninitialized */ > int g_statinit = 1; /* Global statically initialized */ > static int fs_g_uninit; /* File scope uninitialized */ > static int fs_g_statinit = 1; /* File scope statically initialized */ > const int g_const = 1; /* Global constant */ > foo() > { > int local_uninit; /* Auto uninitialized */ > int local_init = 4; /* Auto initialized */ > static int ls_uninit; /* Local static uninitialized */ > static int ls_init = 4; /* Local static initialized */ > } > > Now, I know the scoping rules, and I know the lifetime-of-data rules. > These are not my concern. > > If I understand right: > > g_statinit, fs_g_statinit, and ls_init are all stored in the data > segment, which is allocated and initialized at compile-time, and at > run-time is initially shared by all instances of the executable but is > copy-on-write (per page). (I did not originally realize that the data > segment was loaded copy-on-write; I had thought that a separate copy > was generated for each process.) > Copy-on-write aka `lazy copy' is a detail of the implementation *not* the interface. You must assume that each process gets its own data segment, period. Otherwise you couple your code to the OS implementation. There are a number of reasons why this a bad idea. > g_uninit, fs_g_uninit, and ls_uninit are all stored in the BSS > segment. Memory is reserved in the virtual address space at load > time, but not physically allocated until a page is written to during > run-time. > > local_uninit and local_init are allocated on the stack at run-time. > local_init is initialized at run-time (by code generated by the > compiler) semimmediately after allocation. > > Now, my question originally boiled down to this: does g_const get > allocated in text or data? I was assuming this would be significant > because I thought that text was allocated as shareable, but data had a > separate copy for each process. Now, realizing that data is > copy-on-write, I discover it is not an issue. > I would suspect that const's since they are after all read-only, get put in shareable memory. Whether that's the text segment or not, I don't know. Interestingly, in the following example, strategy 'a' uses *double* the memory of strategy 'b': strategy a: int foobared[] = { 3, 3, 3, 3, 3 }; int foobared[5] = { 3, 3, 3, 3, 3 }; strategy b: const int foobared[] = { 3, 3, 3, 3, 3 }; const int foobared[5] = { 3, 3, 3, 3, 3 }; When you tell me why, you have probably answered your own question. ;) Cheers, Andrew (Opinions are mine, not Nortel's.)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199801151826.KAA18851>