xref: /illumos-gate/usr/src/lib/libc/README (revision 81b2d5738d8e67bdf2438cd3e8c79f379bce44d2)
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21#
22# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25
26The Solaris Process Model Unification project:
27	PSARC/2002/117 Solaris Process Model Unification
28	4470917 Solaris Process Model Unification
29folded libthread into libc and has led to some fundamental changes
30in the rules by which code in libc must be developed and maintained.
31
32All code in libc must be both MT-Safe and Fork-Safe
33and where possible (almost everywhere), Async-Signal-Safe.
34
35To this end, the following rules should be followed:
36
37Almost all internal libc locks (mutexes and read-write locks)
38should be acquired and released via these interfaces:
39
40	mutex_t some_lock = DEFAULTMUTEX;
41
42	lmutex_lock(&some_lock);
43	... do something critical ...
44	lmutex_unlock(&some_lock);
45
46	rwlock_t some_rw_lock = DEFAULTRWLOCK;
47
48	lrw_rdlock(&some_rw_lock);
49	... multiple threads can do something ...
50	lrw_unlock(&some_rw_lock);
51
52	lrw_wrlock(&some_rw_lock);
53	... only one thread can do something ...
54	lrw_unlock(&some_rw_lock);
55
56The above l* versions of the mutex and rwlock interfaces do more
57than the ordinary interfaces:  They define critical regions in
58which the calling thread cannot be suspended (making the region
59fork-safe) and in which the calling thread has all signals deferred
60(making the region async-signal-safe).
61
62However, certain rules apply to the code within these critical regions:
63
64	- The code must be of guaranteed short duration; no calls
65	  to interfaces that might block indefinitely are allowed.
66	  This means no calls into stdio or syslog() and no calls
67	  to cond_wait() unless there is a guarantee of an almost-
68	  immediate call to cond_signal() or cond_broadcast()
69	  from elsewhere.
70
71	- The code cannot call any non-l* synchronization
72	  primitives (mutex_lock(), _private_mutex_lock(),
73	  rw_wrlock(), rw_rdlock(), sema_wait(), etc.)
74
75	- The code cannot call any functions outside of libc,
76	  including application callbacks and functions from
77	  dlopen()ed objects, such as those in the I18N code.
78
79	- Because malloc(), calloc(), realloc(), and free()
80	  are designed to be interposed upon, they fall into
81	  the previous case of prohibition.  None of these can
82	  be called by a thread while in a critical region.
83
84There is a private memory allocator for use internally to libc.
85It cannot be interposed upon and it is safe to use while in
86a critical region (or for that matter while not in a critical
87region; it is async-signal-safe and fork-safe):
88
89	void *lmalloc(size_t);
90	void lfree(void *, size_t);
91
92	void *libc_malloc(size_t);
93	void *libc_realloc(void *, size_t);
94	char *libc_strdup(const char *);
95	void libc_free(void *);
96
97lmalloc() and lfree() are the basic interfaces.  The libc_*()
98variants are built on top of lmalloc()/lfree() but they have
99the same interface signatures as the corresponding functions
100without the 'libc_' prefix.  lmalloc() and libc_malloc()
101return zeroed memory blocks.  Note that lmalloc()/lfree()
102require the caller to remember the size parameter passed
103to lmalloc() and to pass the same value to lfree().
104
105Memory allocated by lmalloc() can only be freed by lfree().
106Memory allocated by libc_malloc(), libc_realloc(), or libc_strdup()
107can only be freed by libc_free().  Never pass such allocated
108memory out of libc if the caller of libc is expected to free it.
109
110lmalloc()/lfree() is a small and simple power of two allocator.
111Do not use it as a general-purpose allocator.  Be kind to it.
112
113There is a special mutual exclusion interface that exists for
114cases, like code in the I18N interfaces, where mutual exclusion
115is required but the above rules cannot be followed:
116
117	int fork_lock_enter(const char *);
118	void fork_lock_exit(void);
119
120fork_lock_enter() does triple-duty.  Not only does it serialize
121calls to fork() and forkall(), but it also serializes calls to
122thr_suspend() (fork() and forkall() also suspend other threads),
123and furthermore it serializes I18N calls to functions in other
124dlopen()ed L10N objects that might be calling malloc()/free().
125Use it in general like this:
126
127	(void) fork_lock_enter(NULL);
128	... serialized; do something that might call malloc ...
129	fork_lock_exit();
130
131The 'const char *' argument to fork_lock_enter() should always
132be NULL except for two special cases:
133	- When called from fork() or forkall()
134	- When called from pthread_atfork()
135This enforces the prohibition against calling fork() or pthread_atfork()
136from a pthread_atfork()-registered fork handler function while a fork()
137prologue or epilogue is in progress.  If _THREAD_ERROR_DETECTION is set
138to 1 or 2 in the environment, such cases will draw a nasty message and
139will dump core if _THREAD_ERROR_DETECTION=2.  fork_lock_enter() returns
140non-zero only if it is called from a fork handler.  This is of interest
141only to callers that have to do something about this condition; the
142return value should be ignored in all other cases (fork_lock_enter()
143never actually fails).
144
145It is an error to call fork_lock_enter() while in a critical region
146(that is, while holding any internal libc lock).
147
148On return from fork_lock_enter(), no internal libc locks are held
149but a flag has been set to cause other callers of fork_lock_enter()
150to delay (via _cond_wait()) until fork_lock_exit() is called.
151
152These are the rules to follow for memory allocation:
153
154  - If a function acquires an internal libc lock or is called while
155    an internal libc lock is held:
156
157	* The malloc family cannot be used.
158
159	* lmalloc or libc_malloc should be used.  The memory must
160	  be released by lfree or libc_free, respectively.
161
162	* lfree takes an argument to tell the size of the releasing
163	  memory.  If the function does not know the size at the
164	  releasing point, libc_malloc and libc_free should be used.
165
166	* As the memory allocated by lmalloc or libc_malloc needs
167	  to be released by lfree or libc_free and these are internal
168	  to libc, they cannot be used to allocate memory that might
169	  be released by application code outside libc.
170
171	* If the memory allocation by malloc() cannot be avoided and
172	  the scalability of the function does not matter much, the
173	  function can be serialized with fork_lock_enter() instead
174	  of lmutex_lock().
175
176	* If the memory allocation by malloc() cannot be avoided and
177	  the scalability of the function does matter, another
178	  implementation of the function will be necessary.
179
180In a DEBUG build of libc:
181	make THREAD_DEBUG=-DTHREAD_DEBUG install
182many of these rules are enforced by ASSERT() statements scattered about
183in the libc sources.  This is the default mode for building libc when
184a DEBUG nightly build is performed.
185
186-----
187
188The putback of the project:
189	6416832 libaio and librt can and should be folded into libc
190introduced several libc-private locking interfaces:
191	void	sig_mutex_lock(mutex_t *);
192	void	sig_mutex_unlock(mutex_t *);
193	int	sig_mutex_trylock(mutex_t *);
194	int	sig_cond_wait(cond_t *, mutex_t *);
195	int	sig_cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
196which are declared in both "thr_uberdata.h" and "mtlib.h".
197
198They are used in specialized code in libc, like the asynchronous i/o code.
199Unlike the lmutex_lock() and lmutex_unlock() interfaces described above,
200these interfaces do not define critical regions, but signals are
201deferred while locks acquired by these functions are held, making
202their use be async-signal safe.  Calls to malloc(), calloc(), realloc(),
203and free() are permissible while holding such locks.
204
205These interfaces were brought over from code in the former libaio
206and librt and are necessary because, where they are used, the code
207must execute potentially long-term waits and must be cancelable.
208sig_cond_wait() and sig_cond_reltimedwait() are cancellation points.
209
210These interfaces are available for other uses inside libc, as
211the need arises.  (There is no need if the code does not perform
212long-term waits.)  Just follow a few rules to be self-consistent:
213 - Don't mix calls to mutex_[un]lock(), lmutex_[un]lock() and
214   sig_mutex_[un]lock() on the same mutex.
215 - Don't call cond_wait() with a mutex acquired by sig_mutex_lock();
216   call sig_cond_wait() or sig_cond_reltimedwait().
217 - Use pthread_cleanup_push() and pthread_cleanup_pop() to make
218   your code cancellation-safe.
219 - The sig_*() interfaces are not in themselves fork-safe.
220   You have to employ other logic to make your code fork-safe.
221   See the tail of postfork1_child() for examples.
222