17c478bd9Sstevel@tonic-gate# 27c478bd9Sstevel@tonic-gate# CDDL HEADER START 37c478bd9Sstevel@tonic-gate# 47c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 5f841f6adSraf# Common Development and Distribution License (the "License"). 6f841f6adSraf# You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate# 87c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate# and limitations under the License. 127c478bd9Sstevel@tonic-gate# 137c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate# 197c478bd9Sstevel@tonic-gate# CDDL HEADER END 207c478bd9Sstevel@tonic-gate# 217c478bd9Sstevel@tonic-gate# 22f841f6adSraf# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate# Use is subject to license terms. 247c478bd9Sstevel@tonic-gate# 257c478bd9Sstevel@tonic-gate 263197aa64SRichard Lowe# Process Model Unification 273197aa64SRichard Lowe 287c478bd9Sstevel@tonic-gateThe Solaris Process Model Unification project: 297c478bd9Sstevel@tonic-gate PSARC/2002/117 Solaris Process Model Unification 307c478bd9Sstevel@tonic-gate 4470917 Solaris Process Model Unification 317c478bd9Sstevel@tonic-gatefolded libthread into libc and has led to some fundamental changes 327c478bd9Sstevel@tonic-gatein the rules by which code in libc must be developed and maintained. 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gateAll code in libc must be both MT-Safe and Fork-Safe 357c478bd9Sstevel@tonic-gateand where possible (almost everywhere), Async-Signal-Safe. 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gateTo this end, the following rules should be followed: 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gateAlmost all internal libc locks (mutexes and read-write locks) 407c478bd9Sstevel@tonic-gateshould be acquired and released via these interfaces: 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate mutex_t some_lock = DEFAULTMUTEX; 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate lmutex_lock(&some_lock); 457c478bd9Sstevel@tonic-gate ... do something critical ... 467c478bd9Sstevel@tonic-gate lmutex_unlock(&some_lock); 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate rwlock_t some_rw_lock = DEFAULTRWLOCK; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate lrw_rdlock(&some_rw_lock); 517c478bd9Sstevel@tonic-gate ... multiple threads can do something ... 527c478bd9Sstevel@tonic-gate lrw_unlock(&some_rw_lock); 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate lrw_wrlock(&some_rw_lock); 557c478bd9Sstevel@tonic-gate ... only one thread can do something ... 567c478bd9Sstevel@tonic-gate lrw_unlock(&some_rw_lock); 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gateThe above l* versions of the mutex and rwlock interfaces do more 597c478bd9Sstevel@tonic-gatethan the ordinary interfaces: They define critical regions in 607c478bd9Sstevel@tonic-gatewhich the calling thread cannot be suspended (making the region 617c478bd9Sstevel@tonic-gatefork-safe) and in which the calling thread has all signals deferred 627c478bd9Sstevel@tonic-gate(making the region async-signal-safe). 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gateHowever, certain rules apply to the code within these critical regions: 657c478bd9Sstevel@tonic-gate 66f841f6adSraf - The code must be of guaranteed short duration; no calls 67f841f6adSraf to interfaces that might block indefinitely are allowed. 68f841f6adSraf This means no calls into stdio or syslog() and no calls 69f841f6adSraf to cond_wait() unless there is a guarantee of an almost- 70f841f6adSraf immediate call to cond_signal() or cond_broadcast() 71f841f6adSraf from elsewhere. 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate - The code cannot call any non-l* synchronization 747c478bd9Sstevel@tonic-gate primitives (mutex_lock(), _private_mutex_lock(), 757c478bd9Sstevel@tonic-gate rw_wrlock(), rw_rdlock(), sema_wait(), etc.) 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate - The code cannot call any functions outside of libc, 787c478bd9Sstevel@tonic-gate including application callbacks and functions from 797c478bd9Sstevel@tonic-gate dlopen()ed objects, such as those in the I18N code. 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate - Because malloc(), calloc(), realloc(), and free() 827c478bd9Sstevel@tonic-gate are designed to be interposed upon, they fall into 837c478bd9Sstevel@tonic-gate the previous case of prohibition. None of these can 847c478bd9Sstevel@tonic-gate be called by a thread while in a critical region. 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gateThere is a private memory allocator for use internally to libc. 877c478bd9Sstevel@tonic-gateIt cannot be interposed upon and it is safe to use while in 887c478bd9Sstevel@tonic-gatea critical region (or for that matter while not in a critical 897c478bd9Sstevel@tonic-gateregion; it is async-signal-safe and fork-safe): 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate void *lmalloc(size_t); 927c478bd9Sstevel@tonic-gate void lfree(void *, size_t); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate void *libc_malloc(size_t); 957c478bd9Sstevel@tonic-gate void *libc_realloc(void *, size_t); 967c478bd9Sstevel@tonic-gate char *libc_strdup(const char *); 977c478bd9Sstevel@tonic-gate void libc_free(void *); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gatelmalloc() and lfree() are the basic interfaces. The libc_*() 1007c478bd9Sstevel@tonic-gatevariants are built on top of lmalloc()/lfree() but they have 1017c478bd9Sstevel@tonic-gatethe same interface signatures as the corresponding functions 1027c478bd9Sstevel@tonic-gatewithout the 'libc_' prefix. lmalloc() and libc_malloc() 1037c478bd9Sstevel@tonic-gatereturn zeroed memory blocks. Note that lmalloc()/lfree() 1047c478bd9Sstevel@tonic-gaterequire the caller to remember the size parameter passed 1057c478bd9Sstevel@tonic-gateto lmalloc() and to pass the same value to lfree(). 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gateMemory allocated by lmalloc() can only be freed by lfree(). 1087c478bd9Sstevel@tonic-gateMemory allocated by libc_malloc(), libc_realloc(), or libc_strdup() 1097c478bd9Sstevel@tonic-gatecan only be freed by libc_free(). Never pass such allocated 1107c478bd9Sstevel@tonic-gatememory out of libc if the caller of libc is expected to free it. 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gatelmalloc()/lfree() is a small and simple power of two allocator. 1137c478bd9Sstevel@tonic-gateDo not use it as a general-purpose allocator. Be kind to it. 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gateThere is a special mutual exclusion interface that exists for 1167c478bd9Sstevel@tonic-gatecases, like code in the I18N interfaces, where mutual exclusion 1177c478bd9Sstevel@tonic-gateis required but the above rules cannot be followed: 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate int fork_lock_enter(const char *); 1207c478bd9Sstevel@tonic-gate void fork_lock_exit(void); 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gatefork_lock_enter() does triple-duty. Not only does it serialize 1237c478bd9Sstevel@tonic-gatecalls to fork() and forkall(), but it also serializes calls to 1247c478bd9Sstevel@tonic-gatethr_suspend() (fork() and forkall() also suspend other threads), 1257c478bd9Sstevel@tonic-gateand furthermore it serializes I18N calls to functions in other 1267c478bd9Sstevel@tonic-gatedlopen()ed L10N objects that might be calling malloc()/free(). 1277c478bd9Sstevel@tonic-gateUse it in general like this: 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate (void) fork_lock_enter(NULL); 1307c478bd9Sstevel@tonic-gate ... serialized; do something that might call malloc ... 1317c478bd9Sstevel@tonic-gate fork_lock_exit(); 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gateThe 'const char *' argument to fork_lock_enter() should always 1347c478bd9Sstevel@tonic-gatebe NULL except for two special cases: 1357c478bd9Sstevel@tonic-gate - When called from fork() or forkall() 1367c478bd9Sstevel@tonic-gate - When called from pthread_atfork() 1377c478bd9Sstevel@tonic-gateThis enforces the prohibition against calling fork() or pthread_atfork() 1387c478bd9Sstevel@tonic-gatefrom a pthread_atfork()-registered fork handler function while a fork() 1397c478bd9Sstevel@tonic-gateprologue or epilogue is in progress. If _THREAD_ERROR_DETECTION is set 1407c478bd9Sstevel@tonic-gateto 1 or 2 in the environment, such cases will draw a nasty message and 1417c478bd9Sstevel@tonic-gatewill dump core if _THREAD_ERROR_DETECTION=2. fork_lock_enter() returns 1427c478bd9Sstevel@tonic-gatenon-zero only if it is called from a fork handler. This is of interest 1437c478bd9Sstevel@tonic-gateonly to callers that have to do something about this condition; the 1447c478bd9Sstevel@tonic-gatereturn value should be ignored in all other cases (fork_lock_enter() 1457c478bd9Sstevel@tonic-gatenever actually fails). 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gateIt is an error to call fork_lock_enter() while in a critical region 1487c478bd9Sstevel@tonic-gate(that is, while holding any internal libc lock). 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gateOn return from fork_lock_enter(), no internal libc locks are held 1517c478bd9Sstevel@tonic-gatebut a flag has been set to cause other callers of fork_lock_enter() 1527c478bd9Sstevel@tonic-gateto delay (via _cond_wait()) until fork_lock_exit() is called. 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gateThese are the rules to follow for memory allocation: 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate - If a function acquires an internal libc lock or is called while 1577c478bd9Sstevel@tonic-gate an internal libc lock is held: 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate * The malloc family cannot be used. 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate * lmalloc or libc_malloc should be used. The memory must 1627c478bd9Sstevel@tonic-gate be released by lfree or libc_free, respectively. 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate * lfree takes an argument to tell the size of the releasing 1657c478bd9Sstevel@tonic-gate memory. If the function does not know the size at the 1667c478bd9Sstevel@tonic-gate releasing point, libc_malloc and libc_free should be used. 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate * As the memory allocated by lmalloc or libc_malloc needs 1697c478bd9Sstevel@tonic-gate to be released by lfree or libc_free and these are internal 1707c478bd9Sstevel@tonic-gate to libc, they cannot be used to allocate memory that might 1717c478bd9Sstevel@tonic-gate be released by application code outside libc. 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate * If the memory allocation by malloc() cannot be avoided and 1747c478bd9Sstevel@tonic-gate the scalability of the function does not matter much, the 1757c478bd9Sstevel@tonic-gate function can be serialized with fork_lock_enter() instead 1767c478bd9Sstevel@tonic-gate of lmutex_lock(). 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate * If the memory allocation by malloc() cannot be avoided and 1797c478bd9Sstevel@tonic-gate the scalability of the function does matter, another 1807c478bd9Sstevel@tonic-gate implementation of the function will be necessary. 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gateIn a DEBUG build of libc: 183*7f9dc0eeSBill Sommerfeld make THREAD_DEBUG=-DDEBUG install 1847c478bd9Sstevel@tonic-gatemany of these rules are enforced by ASSERT() statements scattered about 1857c478bd9Sstevel@tonic-gatein the libc sources. This is the default mode for building libc when 1867c478bd9Sstevel@tonic-gatea DEBUG nightly build is performed. 1877c478bd9Sstevel@tonic-gate 1883197aa64SRichard Lowe# libaio/librt Implementation In libc 1897c478bd9Sstevel@tonic-gate 190f841f6adSrafThe putback of the project: 191f841f6adSraf 6416832 libaio and librt can and should be folded into libc 192f841f6adSrafintroduced several libc-private locking interfaces: 193f841f6adSraf void sig_mutex_lock(mutex_t *); 194f841f6adSraf void sig_mutex_unlock(mutex_t *); 195f841f6adSraf int sig_mutex_trylock(mutex_t *); 196f841f6adSraf int sig_cond_wait(cond_t *, mutex_t *); 197f841f6adSraf int sig_cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *); 198f841f6adSrafwhich are declared in both "thr_uberdata.h" and "mtlib.h". 199f841f6adSraf 200f841f6adSrafThey are used in specialized code in libc, like the asynchronous i/o code. 201f841f6adSrafUnlike the lmutex_lock() and lmutex_unlock() interfaces described above, 202f841f6adSrafthese interfaces do not define critical regions, but signals are 203f841f6adSrafdeferred while locks acquired by these functions are held, making 204f841f6adSraftheir use be async-signal safe. Calls to malloc(), calloc(), realloc(), 205f841f6adSrafand free() are permissible while holding such locks. 206f841f6adSraf 207f841f6adSrafThese interfaces were brought over from code in the former libaio 208f841f6adSrafand librt and are necessary because, where they are used, the code 209f841f6adSrafmust execute potentially long-term waits and must be cancelable. 210f841f6adSrafsig_cond_wait() and sig_cond_reltimedwait() are cancellation points. 211f841f6adSraf 212f841f6adSrafThese interfaces are available for other uses inside libc, as 213f841f6adSrafthe need arises. (There is no need if the code does not perform 214f841f6adSraflong-term waits.) Just follow a few rules to be self-consistent: 215f841f6adSraf - Don't mix calls to mutex_[un]lock(), lmutex_[un]lock() and 216f841f6adSraf sig_mutex_[un]lock() on the same mutex. 217f841f6adSraf - Don't call cond_wait() with a mutex acquired by sig_mutex_lock(); 218f841f6adSraf call sig_cond_wait() or sig_cond_reltimedwait(). 219f841f6adSraf - Use pthread_cleanup_push() and pthread_cleanup_pop() to make 220f841f6adSraf your code cancellation-safe. 221f841f6adSraf - The sig_*() interfaces are not in themselves fork-safe. 222f841f6adSraf You have to employ other logic to make your code fork-safe. 223f841f6adSraf See the tail of postfork1_child() for examples. 2243197aa64SRichard Lowe 2253197aa64SRichard Lowe# Removal Of Synonym Symbols 2263197aa64SRichard Lowe 2273197aa64SRichard LoweThe following project: 2283197aa64SRichard Lowe PSARC 2008/309 expunge synonyms.h 2293197aa64SRichard Lowe 6700179 expunge synonyms.h 2303197aa64SRichard Lowe 2313197aa64SRichard LoweRemoved the historical "synonym" symbols from the C Library. 2323197aa64SRichard Lowe 2333197aa64SRichard LoweHistorically, for every public function symbol in the C library a second, 2343197aa64SRichard Loweprivate, symbol of the same value was defined to be used internally by libc 2353197aa64SRichard Lowe(generally, one or the other will be a weak symbol, precisely which is 2363197aa64SRichard Loweinconsistent). 2373197aa64SRichard Lowe 2383197aa64SRichard LoweThese synonym symbols existed such that an application which provided 2393197aa64SRichard Loweotherwise conflicting symbols could interpose on the version in libc without 2403197aa64SRichard Lowecompromising libc itself, that is if libc defines fopen() which needs open() it 2413197aa64SRichard Lowewould call _open() and an application defined open() would not cause fopen() 2423197aa64SRichard Loweto break. This was made transparent to code within libc via a header, 2433197aa64SRichard Lowesynonyms.h, which would #define open _open, for all such symbols. 2443197aa64SRichard Lowe 2453197aa64SRichard LoweSince ON now uses direct bindings extensively all symbols not explicitly 2463197aa64SRichard Lowemarked "NODIRECT" are directly bound within libc anyway, and none of this is 2473197aa64SRichard Loweactually necessary. Thus synonyms.h was removed, and no new synonym symbols 2483197aa64SRichard Loweneed be added. However, unfortunately, certain of the private symbols were 2493197aa64SRichard Loweinadvertently exposed to applications, and several are known to have been 2503197aa64SRichard Loweused, thus these existing synonyms must continue to exist to maintain 2513197aa64SRichard Lowecompatibility. A preloadable library, /lib/c_synonyms.so.1 is provided which 2523197aa64SRichard Lowealso provides the historical names with underscore prefixes to allow any other 2533197aa64SRichard Loweincorrect application to continue to function. 2543197aa64SRichard Lowe 2553197aa64SRichard LoweIt should never be necessary to add additional synonym symbols to libc nor to 2563197aa64SRichard Loweadd underscore prefixed aliases to c_synonyms.so.1. 2573197aa64SRichard Lowe 2583197aa64SRichard Lowe# libc Internals Scoped Protected 2593197aa64SRichard Lowe 2603197aa64SRichard LoweThe integration of the fix for: 2613197aa64SRichard Lowe 6689238 libc needs global protection against ld.so.1 2623197aa64SRichard Lowe 2633197aa64SRichard LoweScopes all function symbols within libc protected, excepting those that need 2643197aa64SRichard Loweto be accepting of interposition and to have a consistent version called both 2653197aa64SRichard Lowewithin and without libc (basically, the malloc() family). 2663197aa64SRichard Lowe 2673197aa64SRichard LoweThis causes references by libc to itself to be permanently and unavoidably 2683197aa64SRichard Lowebound, and thus to never enter ld.so (and potentially from there audit 2693197aa64SRichard Lowelibraries or other such support libraries). This maintains an otherwise 2703197aa64SRichard Lowecomplicated to verify invariant: within critical sections (with any internal 2713197aa64SRichard Lowelock held, etc) execution can never leave the context of libc. Previously 2723197aa64SRichard Lowethis was done with a selection of known-to-be-problematic functions having 2733197aa64SRichard Loweweak synonyms scoped private, but this was both difficult to verify, difficult 2743197aa64SRichard Loweto remember, and thus always at least somewhat incomplete. 2753197aa64SRichard Lowe 2763197aa64SRichard LoweIn summary, any new function symbol in libc must be scoped protected unless it 2773197aa64SRichard Loweis one of a very small group of functions that must allow interposed versions 2783197aa64SRichard Loweto be bound to from the C library itself -- it is grossly unlikely that more 2793197aa64SRichard Loweof these will occur. 280