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