xref: /onnv-gate/usr/src/lib/libc/README (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#
2*0Sstevel@tonic-gate# CDDL HEADER START
3*0Sstevel@tonic-gate#
4*0Sstevel@tonic-gate# The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate# (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate# with the License.
8*0Sstevel@tonic-gate#
9*0Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate# See the License for the specific language governing permissions
12*0Sstevel@tonic-gate# and limitations under the License.
13*0Sstevel@tonic-gate#
14*0Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate#
20*0Sstevel@tonic-gate# CDDL HEADER END
21*0Sstevel@tonic-gate#
22*0Sstevel@tonic-gate#
23*0Sstevel@tonic-gate# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate# Use is subject to license terms.
25*0Sstevel@tonic-gate#
26*0Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
27*0Sstevel@tonic-gate#
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gateThe Solaris Process Model Unification project:
30*0Sstevel@tonic-gate	PSARC/2002/117 Solaris Process Model Unification
31*0Sstevel@tonic-gate	4470917 Solaris Process Model Unification
32*0Sstevel@tonic-gatefolded libthread into libc and has led to some fundamental changes
33*0Sstevel@tonic-gatein the rules by which code in libc must be developed and maintained.
34*0Sstevel@tonic-gate
35*0Sstevel@tonic-gateAll code in libc must be both MT-Safe and Fork-Safe
36*0Sstevel@tonic-gateand where possible (almost everywhere), Async-Signal-Safe.
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gateTo this end, the following rules should be followed:
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gateAlmost all internal libc locks (mutexes and read-write locks)
41*0Sstevel@tonic-gateshould be acquired and released via these interfaces:
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate	mutex_t some_lock = DEFAULTMUTEX;
44*0Sstevel@tonic-gate
45*0Sstevel@tonic-gate	lmutex_lock(&some_lock);
46*0Sstevel@tonic-gate	... do something critical ...
47*0Sstevel@tonic-gate	lmutex_unlock(&some_lock);
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gate	rwlock_t some_rw_lock = DEFAULTRWLOCK;
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gate	lrw_rdlock(&some_rw_lock);
52*0Sstevel@tonic-gate	... multiple threads can do something ...
53*0Sstevel@tonic-gate	lrw_unlock(&some_rw_lock);
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gate	lrw_wrlock(&some_rw_lock);
56*0Sstevel@tonic-gate	... only one thread can do something ...
57*0Sstevel@tonic-gate	lrw_unlock(&some_rw_lock);
58*0Sstevel@tonic-gate
59*0Sstevel@tonic-gateThe above l* versions of the mutex and rwlock interfaces do more
60*0Sstevel@tonic-gatethan the ordinary interfaces:  They define critical regions in
61*0Sstevel@tonic-gatewhich the calling thread cannot be suspended (making the region
62*0Sstevel@tonic-gatefork-safe) and in which the calling thread has all signals deferred
63*0Sstevel@tonic-gate(making the region async-signal-safe).
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gateHowever, certain rules apply to the code within these critical regions:
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gate	- The code must be of guaranteed short duration; no
68*0Sstevel@tonic-gate	  calls to interfaces that might block indefinitely are
69*0Sstevel@tonic-gate	  allowed.  This means no calls into stdio or syslog().
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gate	- The code cannot call any non-l* synchronization
72*0Sstevel@tonic-gate	  primitives (mutex_lock(), _private_mutex_lock(),
73*0Sstevel@tonic-gate	  rw_wrlock(), rw_rdlock(), sema_wait(), etc.)
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gate	- The code cannot call any functions outside of libc,
76*0Sstevel@tonic-gate	  including application callbacks and functions from
77*0Sstevel@tonic-gate	  dlopen()ed objects, such as those in the I18N code.
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate	- Because malloc(), calloc(), realloc(), and free()
80*0Sstevel@tonic-gate	  are designed to be interposed upon, they fall into
81*0Sstevel@tonic-gate	  the previous case of prohibition.  None of these can
82*0Sstevel@tonic-gate	  be called by a thread while in a critical region.
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gateThere is a private memory allocator for use internally to libc.
85*0Sstevel@tonic-gateIt cannot be interposed upon and it is safe to use while in
86*0Sstevel@tonic-gatea critical region (or for that matter while not in a critical
87*0Sstevel@tonic-gateregion; it is async-signal-safe and fork-safe):
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate	void *lmalloc(size_t);
90*0Sstevel@tonic-gate	void lfree(void *, size_t);
91*0Sstevel@tonic-gate
92*0Sstevel@tonic-gate	void *libc_malloc(size_t);
93*0Sstevel@tonic-gate	void *libc_realloc(void *, size_t);
94*0Sstevel@tonic-gate	char *libc_strdup(const char *);
95*0Sstevel@tonic-gate	void libc_free(void *);
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gatelmalloc() and lfree() are the basic interfaces.  The libc_*()
98*0Sstevel@tonic-gatevariants are built on top of lmalloc()/lfree() but they have
99*0Sstevel@tonic-gatethe same interface signatures as the corresponding functions
100*0Sstevel@tonic-gatewithout the 'libc_' prefix.  lmalloc() and libc_malloc()
101*0Sstevel@tonic-gatereturn zeroed memory blocks.  Note that lmalloc()/lfree()
102*0Sstevel@tonic-gaterequire the caller to remember the size parameter passed
103*0Sstevel@tonic-gateto lmalloc() and to pass the same value to lfree().
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gateMemory allocated by lmalloc() can only be freed by lfree().
106*0Sstevel@tonic-gateMemory allocated by libc_malloc(), libc_realloc(), or libc_strdup()
107*0Sstevel@tonic-gatecan only be freed by libc_free().  Never pass such allocated
108*0Sstevel@tonic-gatememory out of libc if the caller of libc is expected to free it.
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gatelmalloc()/lfree() is a small and simple power of two allocator.
111*0Sstevel@tonic-gateDo not use it as a general-purpose allocator.  Be kind to it.
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gateThere is a special mutual exclusion interface that exists for
114*0Sstevel@tonic-gatecases, like code in the I18N interfaces, where mutual exclusion
115*0Sstevel@tonic-gateis required but the above rules cannot be followed:
116*0Sstevel@tonic-gate
117*0Sstevel@tonic-gate	int fork_lock_enter(const char *);
118*0Sstevel@tonic-gate	void fork_lock_exit(void);
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gatefork_lock_enter() does triple-duty.  Not only does it serialize
121*0Sstevel@tonic-gatecalls to fork() and forkall(), but it also serializes calls to
122*0Sstevel@tonic-gatethr_suspend() (fork() and forkall() also suspend other threads),
123*0Sstevel@tonic-gateand furthermore it serializes I18N calls to functions in other
124*0Sstevel@tonic-gatedlopen()ed L10N objects that might be calling malloc()/free().
125*0Sstevel@tonic-gateUse it in general like this:
126*0Sstevel@tonic-gate
127*0Sstevel@tonic-gate	(void) fork_lock_enter(NULL);
128*0Sstevel@tonic-gate	... serialized; do something that might call malloc ...
129*0Sstevel@tonic-gate	fork_lock_exit();
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gateThe 'const char *' argument to fork_lock_enter() should always
132*0Sstevel@tonic-gatebe NULL except for two special cases:
133*0Sstevel@tonic-gate	- When called from fork() or forkall()
134*0Sstevel@tonic-gate	- When called from pthread_atfork()
135*0Sstevel@tonic-gateThis enforces the prohibition against calling fork() or pthread_atfork()
136*0Sstevel@tonic-gatefrom a pthread_atfork()-registered fork handler function while a fork()
137*0Sstevel@tonic-gateprologue or epilogue is in progress.  If _THREAD_ERROR_DETECTION is set
138*0Sstevel@tonic-gateto 1 or 2 in the environment, such cases will draw a nasty message and
139*0Sstevel@tonic-gatewill dump core if _THREAD_ERROR_DETECTION=2.  fork_lock_enter() returns
140*0Sstevel@tonic-gatenon-zero only if it is called from a fork handler.  This is of interest
141*0Sstevel@tonic-gateonly to callers that have to do something about this condition; the
142*0Sstevel@tonic-gatereturn value should be ignored in all other cases (fork_lock_enter()
143*0Sstevel@tonic-gatenever actually fails).
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gateIt is an error to call fork_lock_enter() while in a critical region
146*0Sstevel@tonic-gate(that is, while holding any internal libc lock).
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gateOn return from fork_lock_enter(), no internal libc locks are held
149*0Sstevel@tonic-gatebut a flag has been set to cause other callers of fork_lock_enter()
150*0Sstevel@tonic-gateto delay (via _cond_wait()) until fork_lock_exit() is called.
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gateThese are the rules to follow for memory allocation:
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate  - If a function acquires an internal libc lock or is called while
155*0Sstevel@tonic-gate    an internal libc lock is held:
156*0Sstevel@tonic-gate
157*0Sstevel@tonic-gate	* The malloc family cannot be used.
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate	* lmalloc or libc_malloc should be used.  The memory must
160*0Sstevel@tonic-gate	  be released by lfree or libc_free, respectively.
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate	* lfree takes an argument to tell the size of the releasing
163*0Sstevel@tonic-gate	  memory.  If the function does not know the size at the
164*0Sstevel@tonic-gate	  releasing point, libc_malloc and libc_free should be used.
165*0Sstevel@tonic-gate
166*0Sstevel@tonic-gate	* As the memory allocated by lmalloc or libc_malloc needs
167*0Sstevel@tonic-gate	  to be released by lfree or libc_free and these are internal
168*0Sstevel@tonic-gate	  to libc, they cannot be used to allocate memory that might
169*0Sstevel@tonic-gate	  be released by application code outside libc.
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gate	* If the memory allocation by malloc() cannot be avoided and
172*0Sstevel@tonic-gate	  the scalability of the function does not matter much, the
173*0Sstevel@tonic-gate	  function can be serialized with fork_lock_enter() instead
174*0Sstevel@tonic-gate	  of lmutex_lock().
175*0Sstevel@tonic-gate
176*0Sstevel@tonic-gate	* If the memory allocation by malloc() cannot be avoided and
177*0Sstevel@tonic-gate	  the scalability of the function does matter, another
178*0Sstevel@tonic-gate	  implementation of the function will be necessary.
179*0Sstevel@tonic-gate
180*0Sstevel@tonic-gateIn a DEBUG build of libc:
181*0Sstevel@tonic-gate	make THREAD_DEBUG=-DTHREAD_DEBUG install
182*0Sstevel@tonic-gatemany of these rules are enforced by ASSERT() statements scattered about
183*0Sstevel@tonic-gatein the libc sources.  This is the default mode for building libc when
184*0Sstevel@tonic-gatea DEBUG nightly build is performed.
185*0Sstevel@tonic-gate
186*0Sstevel@tonic-gate-----
187*0Sstevel@tonic-gate
188*0Sstevel@tonic-gateSome i18n code cannot be distributed as open source.  To enable the rest of
189*0Sstevel@tonic-gatelibc to be distributed as open source, those i18n files now live in a
190*0Sstevel@tonic-gateseparate libc_i18n directory.  Those source files are position-independently
191*0Sstevel@tonic-gatecompiled and are archived into the libc_i18n.a library.  The libc_i18n.a
192*0Sstevel@tonic-gatearchive library is installed into the $(ROOTFS_LIBDIR) and
193*0Sstevel@tonic-gate$(ROOTFS_LIBDIR64) directories.  During link phase, libc.so.1 links with
194*0Sstevel@tonic-gatelibc_i18n.a in the proto area.  Therefore, the build of the libc_i18n tree
195*0Sstevel@tonic-gateneeds to be done before the build of the libc tree.  Also the compilation
196*0Sstevel@tonic-gateconditions such as the setting of CFLAGS and CPPFLAGS for the libc_i18n
197*0Sstevel@tonic-gatestuff need to be compatible with the ones for the libc stuff.  Whenever
198*0Sstevel@tonic-gatechanges that affect the compilation conditions of libc occur, the changes
199*0Sstevel@tonic-gateshould be propagated to libc_i18n.
200