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>
