README revision f841f6ad96ea6675d6c6b35c749eaac601799fdf
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# CDDL HEADER START
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# The contents of this file are subject to the terms of the
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# Common Development and Distribution License (the "License").
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# You may not use this file except in compliance with the License.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# or http://www.opensolaris.org/os/licensing.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# See the License for the specific language governing permissions
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# and limitations under the License.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# When distributing Covered Code, include this CDDL HEADER in each
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# If applicable, add the following below this CDDL HEADER, with the
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# fields enclosed by brackets "[]" replaced with your own identifying
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# information: Portions Copyright [yyyy] [name of copyright owner]
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# CDDL HEADER END
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# Use is subject to license terms.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai# ident "%Z%%M% %I% %E% SMI"
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai#
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThe Solaris Process Model Unification project:
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai PSARC/2002/117 Solaris Process Model Unification
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai 4470917 Solaris Process Model Unification
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaifolded libthread into libc and has led to some fundamental changes
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiin the rules by which code in libc must be developed and maintained.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiAll code in libc must be both MT-Safe and Fork-Safe
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiand where possible (almost everywhere), Async-Signal-Safe.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiTo this end, the following rules should be followed:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiAlmost all internal libc locks (mutexes and read-write locks)
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaishould be acquired and released via these interfaces:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai mutex_t some_lock = DEFAULTMUTEX;
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai lmutex_lock(&some_lock);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai ... do something critical ...
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai lmutex_unlock(&some_lock);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai rwlock_t some_rw_lock = DEFAULTRWLOCK;
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai lrw_rdlock(&some_rw_lock);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai ... multiple threads can do something ...
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai lrw_unlock(&some_rw_lock);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai lrw_wrlock(&some_rw_lock);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai ... only one thread can do something ...
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai lrw_unlock(&some_rw_lock);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThe above l* versions of the mutex and rwlock interfaces do more
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaithan the ordinary interfaces: They define critical regions in
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiwhich the calling thread cannot be suspended (making the region
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaifork-safe) and in which the calling thread has all signals deferred
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai(making the region async-signal-safe).
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiHowever, certain rules apply to the code within these critical regions:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - The code must be of guaranteed short duration; no calls
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai to interfaces that might block indefinitely are allowed.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai This means no calls into stdio or syslog() and no calls
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai to cond_wait() unless there is a guarantee of an almost-
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai immediate call to cond_signal() or cond_broadcast()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai from elsewhere.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - The code cannot call any non-l* synchronization
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai primitives (mutex_lock(), _private_mutex_lock(),
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai rw_wrlock(), rw_rdlock(), sema_wait(), etc.)
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - The code cannot call any functions outside of libc,
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai including application callbacks and functions from
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai dlopen()ed objects, such as those in the I18N code.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - Because malloc(), calloc(), realloc(), and free()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai are designed to be interposed upon, they fall into
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai the previous case of prohibition. None of these can
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai be called by a thread while in a critical region.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThere is a private memory allocator for use internally to libc.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiIt cannot be interposed upon and it is safe to use while in
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaia critical region (or for that matter while not in a critical
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desairegion; it is async-signal-safe and fork-safe):
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void *lmalloc(size_t);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void lfree(void *, size_t);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void *libc_malloc(size_t);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void *libc_realloc(void *, size_t);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai char *libc_strdup(const char *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void libc_free(void *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desailmalloc() and lfree() are the basic interfaces. The libc_*()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaivariants are built on top of lmalloc()/lfree() but they have
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaithe same interface signatures as the corresponding functions
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiwithout the 'libc_' prefix. lmalloc() and libc_malloc()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaireturn zeroed memory blocks. Note that lmalloc()/lfree()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desairequire the caller to remember the size parameter passed
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaito lmalloc() and to pass the same value to lfree().
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiMemory allocated by lmalloc() can only be freed by lfree().
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiMemory allocated by libc_malloc(), libc_realloc(), or libc_strdup()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaican only be freed by libc_free(). Never pass such allocated
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaimemory out of libc if the caller of libc is expected to free it.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desailmalloc()/lfree() is a small and simple power of two allocator.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiDo not use it as a general-purpose allocator. Be kind to it.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThere is a special mutual exclusion interface that exists for
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaicases, like code in the I18N interfaces, where mutual exclusion
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiis required but the above rules cannot be followed:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai int fork_lock_enter(const char *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void fork_lock_exit(void);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaifork_lock_enter() does triple-duty. Not only does it serialize
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaicalls to fork() and forkall(), but it also serializes calls to
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaithr_suspend() (fork() and forkall() also suspend other threads),
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiand furthermore it serializes I18N calls to functions in other
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaidlopen()ed L10N objects that might be calling malloc()/free().
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiUse it in general like this:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai (void) fork_lock_enter(NULL);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai ... serialized; do something that might call malloc ...
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai fork_lock_exit();
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThe 'const char *' argument to fork_lock_enter() should always
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaibe NULL except for two special cases:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - When called from fork() or forkall()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - When called from pthread_atfork()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThis enforces the prohibition against calling fork() or pthread_atfork()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaifrom a pthread_atfork()-registered fork handler function while a fork()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiprologue or epilogue is in progress. If _THREAD_ERROR_DETECTION is set
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaito 1 or 2 in the environment, such cases will draw a nasty message and
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiwill dump core if _THREAD_ERROR_DETECTION=2. fork_lock_enter() returns
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desainon-zero only if it is called from a fork handler. This is of interest
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaionly to callers that have to do something about this condition; the
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaireturn value should be ignored in all other cases (fork_lock_enter()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desainever actually fails).
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiIt is an error to call fork_lock_enter() while in a critical region
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai(that is, while holding any internal libc lock).
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiOn return from fork_lock_enter(), no internal libc locks are held
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaibut a flag has been set to cause other callers of fork_lock_enter()
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaito delay (via _cond_wait()) until fork_lock_exit() is called.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThese are the rules to follow for memory allocation:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai - If a function acquires an internal libc lock or is called while
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai an internal libc lock is held:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai * The malloc family cannot be used.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai * lmalloc or libc_malloc should be used. The memory must
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai be released by lfree or libc_free, respectively.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai * lfree takes an argument to tell the size of the releasing
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai memory. If the function does not know the size at the
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai releasing point, libc_malloc and libc_free should be used.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai * As the memory allocated by lmalloc or libc_malloc needs
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai to be released by lfree or libc_free and these are internal
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai to libc, they cannot be used to allocate memory that might
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai be released by application code outside libc.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai * If the memory allocation by malloc() cannot be avoided and
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai the scalability of the function does not matter much, the
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai function can be serialized with fork_lock_enter() instead
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai of lmutex_lock().
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai * If the memory allocation by malloc() cannot be avoided and
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai the scalability of the function does matter, another
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai implementation of the function will be necessary.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiIn a DEBUG build of libc:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai make THREAD_DEBUG=-DTHREAD_DEBUG install
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaimany of these rules are enforced by ASSERT() statements scattered about
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiin the libc sources. This is the default mode for building libc when
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaia DEBUG nightly build is performed.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai-----
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiSome i18n code cannot be distributed as open source. To enable the rest of
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desailibc to be distributed as open source, those i18n files now live in a
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiseparate libc_i18n directory. Those source files are position-independently
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaicompiled and are archived into the libc_i18n.a library. The libc_i18n.a
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiarchive library is installed into the $(ROOTFS_LIBDIR) and
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai$(ROOTFS_LIBDIR64) directories. During link phase, libc.so.1 links with
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desailibc_i18n.a in the proto area. Therefore, the build of the libc_i18n tree
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaineeds to be done before the build of the libc tree. Also the compilation
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiconditions such as the setting of CFLAGS and CPPFLAGS for the libc_i18n
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaistuff need to be compatible with the ones for the libc stuff. Whenever
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaichanges that affect the compilation conditions of libc occur, the changes
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaishould be propagated to libc_i18n.
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai-----
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThe putback of the project:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai 6416832 libaio and librt can and should be folded into libc
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiintroduced several libc-private locking interfaces:
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void sig_mutex_lock(mutex_t *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai void sig_mutex_unlock(mutex_t *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai int sig_mutex_trylock(mutex_t *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai int sig_cond_wait(cond_t *, mutex_t *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai int sig_cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desaiwhich are declared in both "thr_uberdata.h" and "mtlib.h".
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen Desai
52df2f0673e47b3a77ac1ab47e2fd49af1ff7b5aSatyen DesaiThey are used in specialized code in libc, like the asynchronous i/o code.
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiUnlike the lmutex_lock() and lmutex_unlock() interfaces described above,
these interfaces do not define critical regions, but signals are
deferred while locks acquired by these functions are held, making
their use be async-signal safe. Calls to malloc(), calloc(), realloc(),
and free() are permissible while holding such locks.
These interfaces were brought over from code in the former libaio
and librt and are necessary because, where they are used, the code
must execute potentially long-term waits and must be cancelable.
sig_cond_wait() and sig_cond_reltimedwait() are cancellation points.
These interfaces are available for other uses inside libc, as
the need arises. (There is no need if the code does not perform
long-term waits.) Just follow a few rules to be self-consistent:
- Don't mix calls to mutex_[un]lock(), lmutex_[un]lock() and
sig_mutex_[un]lock() on the same mutex.
- Don't call cond_wait() with a mutex acquired by sig_mutex_lock();
call sig_cond_wait() or sig_cond_reltimedwait().
- Use pthread_cleanup_push() and pthread_cleanup_pop() to make
your code cancellation-safe.
- The sig_*() interfaces are not in themselves fork-safe.
You have to employ other logic to make your code fork-safe.
See the tail of postfork1_child() for examples.