diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-11-24 10:17:24 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-11-24 10:17:24 +0000 |
commit | dfb5fe2dee1b64c57c3df7fc4c0ecb7ad0450730 (patch) | |
tree | cc3db9a916b8d9821f142b97a3200bad61c3975e | |
parent | 1df709beaf6f88e7906d427be4f0c7dcf12e8a55 (diff) |
Move the FAQ. Add a docs dir. Add in a report on thread support.
-Erik
-rw-r--r-- | docs/FAQ.txt (renamed from FAQ.txt) | 22 | ||||
-rw-r--r-- | docs/threads.txt | 2275 |
2 files changed, 2293 insertions, 4 deletions
@@ -5,6 +5,20 @@ have additions to this FAQ document, I'd love to add them, -Erik +Q: What platforms does uClibc run on? + + Currently uClibc runs on arm, i386, m68k, mipsel, powerpc, sh, + sparc, and v850. + + + +Q: Does uClibc support shared libraries? + + Yes. uClibc has shared library support on x86, arm, and powerpc. + Shared Libraries are _not_ currently supported on MMU-less systems. + + + Q: Why is it called uClibc? The letter 'u' is short for the greek letter "mu". "Mu" stands for @@ -37,6 +51,7 @@ Q: Why are you doing this? Whats wrong with glibc? not wanted in embedded systems." 24 May 1999 + Q: So uClibc is smaller then glibc? Doesn't that mean it completely sucks? How could it be smaller and not suck? @@ -72,7 +87,6 @@ Q: Why should I use uClibc? - Q: I want to create a closed source commercial application and I want to protect my intellectual property. If I use uClibc, don't I have to release my source code? @@ -110,6 +124,7 @@ Q: How do I compile stuff? Q: How do I make autoconf and automake behave? + First run export PATH=/usr/i386-linux-uclibc/bin:$PATH (or similar adjusted for your target architecture) then run you can simply @@ -135,7 +150,6 @@ Q: I need you to add <favorite feature> now! How come you don't answer all my questions on the mailing list withing 5 minutes? I demand that you help me Right Now! - You have not paid me a single cent and yet you still have the product of over year and a half of my work, and lots of work from other people. How dare you treat me that way! I work on uClibc because I find it @@ -146,11 +160,11 @@ Q: I need you to add <favorite feature> now! How come you don't answer all my Q: I need you to add <favorite feature>! Are the uClibc developers willing to be paid in order to add in <favorite feature>? Are you willing to provide support contracts? - Sure! Now you have our attention! What you should do is contact Erik Andersen of CodePoet Consulting to bid on your project. If Erik - is too busy to personally add your feature + is too busy to personally add your feature, there are several other + active contributors who may be able to help you out. Q: I think you guys are great and I want to help support your work! diff --git a/docs/threads.txt b/docs/threads.txt new file mode 100644 index 000000000..2d5d9e623 --- /dev/null +++ b/docs/threads.txt @@ -0,0 +1,2275 @@ +uClibc thread-safety analysis +By Steve Thayer <sthayer@coactive.com> +with updates by Erik Andersen <andersee@debian.org> + +Introduction: + +The purpose of this document is to identify the things that need to be done +to the uClibc C library in order to make it thread-safe. The goal is to be +able to use a pthreads thread implementation under uClinux, using the uClibc +C library. To help identify the things that require changing, I used David R. +Butenhof's book Programming With POSIX Threads, the source code for the +glibc 2.1.3 C library, and the source code for the C library included in the +Proventhreads distribution. + +References: + +Butenhof, David R., Programming With POSIX Threads, Addison Wesley Longman, Inc., Reading, MA, ISBN 0-201-63392-2, 1997. + + +The GNU C library is available from the Free Software Foundation +http://www.gnu.org/software/libc/libc.html + +Proventhreads is part of the Inferno Operating system. +http://www.vitanuova.com/inferno/index.html + + +1. Stdio: + +1.1 Buffer access mutexes + + The following functions are required in order to protect shared + I/O buffers from being accessed by more than one thread at a time. + None of these functions are currently implemented in the uClibc + library, so they must be added. + + flockfile <required> <--- + ftrylockfile <required> <--- + funlockfile <required> <--- + +1.2 Functions that must use buffer access mutexes, according to Butenhof + + The following functions are identified by Butenhof as needing to use + buffer access mutexes. This does not represent all functions that + need to use the mutexes. + + getc <mutex required> <--- + getchar <mutex required> <--- + putc <mutex required> <--- + putchar <mutex required> <--- + +1.3 Functions from glibc (libio) that use buffer access mutexes + + The following functions are functions found in glibc that currently + use the buffer access mutexes. Comments in brackets represent + status of uClibc with regard to these functions. Most of these + functions aren't even supported under uClibc, so no work is required. + The rest may require the access mutex. (These must be analyzed on a + case-by-case basis.) + + clearerr <mutex required> <--- + feof <mutex required> <--- + ferror <mutex required> <--- + fputc <mutex required> <--- + fputwc <not supported> + freopen <mutex required> <--- + freopen64 <not supported> + fseek <mutex required> <--- + fseeko <not supported> + fseeko64 <not supported> + ftello <not supported> + ftello64 <not supported> + fwide <not supported> + getc <macro for fgetc> + getchar <macro for fgetc> + getwc <not supported> + getwchar <not supported> + iofclose <not supported> + iofflush <not supported> + iofgetpos <not supported> + iofgetpos64 <not supported> + iofgets <not supported> + iofgetws <not supported> + iofputs <not supported> + iofputws <not supported> + iofread <not supported> + iofsetpos <not supported> + iofsetpos64 <not supported> + ioftell <not supported> + iofwrite <not supported> + iogetdelim <not supported> + iogets <not supported> + ioputs <not supported> + ioseekoff <not supported> + ioseekpos <not supported> + iosetbuffer <not supported> + iosetvbuf <not supported> + ioungetc <not supported> + ioungetwc <not supported> + oldiofclose <not supported> + oldiofgetpos <not supported> + oldiofgetpos64 <not supported> + oldiofsetpos <not supported> + oldiofsetpos64 <not supported> + peekc <not supported> + putc <macro for fputc> + putchar <macro for fputc> + putwc <not supported> + putwchar <not supported> + rewind <mutex required> <--- + +1.4 Functions from Proventhreads that use buffer access mutexes + + See description above. This applies only to the C library included + in the proventhreads distribution. + + clearerr <mutex required> <--- + fclose <mutex required> <--- + fflush <mutex required> <--- + fgetc <mutex required> <--- + __getc <not supported> + fgetline <not supported> + fgetpos <mutex required> <--- + fgets <mutex required> <--- + fpurge <not supported> + fputc <mutex required> <--- + __putc <not supported> + fputs <mutex required> <--- + fread <mutex required> <--- + freopen <mutex required> <--- + fscanf <mutex required> <--- + fseek <mutex required> <--- + ftell <mutex required> <--- + fwalk <not supported> + fwrite <mutex required> <--- + getc <macro for fgetc> + getchar <mutex required> <--- + putc <macro for fputc> + putchar <mutex required> <--- + puts <mutex required> <--- + putw <not supported> + refill <not supported> + rewind <mutex required> <--- + scanf <mutex required> <--- + setvbuf <mutex required> <--- + ungetc <mutex required> <--- + vfprintf <mutex required> <--- + vscanf <mutex required> <--- + +1.5 Unlocked buffer access + + These functions get used in situations where speed is important, + and locking isn't necessary, or for use in a section of code that + is already locked. For example, a for-loop that makes multiple calls + to getc could make an exlicit call to flockfile outside the loop, and + then use getc_unlocked within the loop for speed. That way, the lock + only needs to be grabbed and released once, rather than for each call. + + getc_unlocked <required> <--- + getchar_unlocked <required> <--- + putc_unlocked <required> <--- + putchar_unlocked <required> <--- + +1.6 Additional unlocked calls made in glibc + + These are additional functions (not mentioned by Butenhof) that the + glibc library uses for unlocked buffer access. Though not strictly + necessary, these may be nice to have in uClibc. + + fileno_unlocked <desired> <--- + clearerr_unlocked <desired> <--- + feof_unlocked <desired> <--- + ferror_unlocked <desired> <--- + fputc_unlocked <desired> <--- + fgetc_unlocked <desired> <--- + fflush_unlocked <desired> <--- + fread_unlocked <desired> <--- + fwrite_unlocked <desired> <--- + fgets_unlocked <desired> <--- + fputs_unlocked <desired> <--- + +1.7 Additional unlocked calls made in Proventhreads + + Proventhreads only provides the four unlocked function calls above. + + <none> + + +2. Thread-safe functions: + + There are some functions in the C library standard that are + simply not thread-safe and cannot be thread-safe using their + current interface. For example, any function that returns a + pointer to static data, or requires static context between + calls. To resolve this problem, new functions were added to + the standard that perform the same basic task, but use a new + interface that does not require static data. These functions + share their name with the old unsafe functions, but have an + "_r" appended to the name. By definition, these functions are + reentrant and thread-safe. It is important to note that these + functions to do not depend on <pthread.h> and can be used even + if threading is not supported. + +2.1 User and terminal identification: + + getlogin_r <implemented> + ctermid <implemented> (1) + ttyname_r <required> <--- + + 1. ctermid is a special case. The signature has not changed, but a + requirement has been added that its parameter point to a structure + of exactly L_ctermid bytes. + +2.2 Directory searching + + readdir_r <required> <--- + +2.3 String token + + strtok_r <implemented> + +2.4 Time representation + + asctime_r <implemented> + ctime_r <implemented> + gmtime_r <implemented> + localtime_r <implemented> + +2.5 Random number generation + + rand_r <required> <--- + +2.6 Group and user database + + getgrgid_r <required> <--- + getgrnam_r <required> <--- + getpwuid_r <implemented> + getpwnam_r <implemented> + +2.7 Additional thread-safe functions implemented by glibc + + The following is a list of additional functions implemented by glibc + that also provide thread-safe functionality. Most of these functions + are not supported by uClibc, so there is no need to implement the + thread-safe version. Those that do apply, but have not been + implemented yet are highlighted. + + __fgetpwent_r <not supported> + fgetpwent_r <implemented> + __ttyname_r <not supported> + getttyname_r <not supported> + __getmntent_r <not supported> + getmntent_r <desired> <--- + ecvt_r <not supported> + fcvt_r <not supported> + qecvt_r <not supported> + qfcvt_r <not supported> + hcreate_r <not supported> + hdestroy_r <not supported> + hsearch_r <not supported> + __getspent_r <not supported> + getspent_r <not supported> + __getspnam_r <not supported> + getspnam_r <not supported> + __sgetspent_r <not supported> + sgetspent_r <not supported> + __fgetspent_r <not supported> + fgetspent_r <not supported> + __gethostbyaddr_r <not supported> + gethostbyaddr_r <desired> <--- + __gethostbyname2_r <not supported> + gethostbyname2_r <not supported> + __gethostbyname_r <not supported> + gethostbyname_r <desired> <--- + __gethostent_r <not supported + gethostent_r <not supported> + __getnetbyaddr_r <not supported> + getnetbyaddr_r <desired> <--- + __getnetent_r <not supported> + getnetent_r <desired> <--- + __getnetbyname_r <not supported> + getnetbyname_r <desired> <--- + __getprotobynumber_r <not supported> + getprotobynumber_r <desired> <--- + __getprotoent_r <not supported> + getprotoent_r <desired> <--- + __getprotobyname_r <not supported> + getprotobyname_r <desired> <--- + __getservbyname_r <not supported> + getservbyname_r <desired> <--- + __getservbyport_r <not supported> + getservbyport_r <desired> <--- + __getservent_r <not supported> + getservent_r <desired> <--- + __getrpcent_r <not supported> + getrpcent_r <desired> <--- + __getrpcbyname_r <not supported> + getrpcbyname_r <desired> <--- + __getrpcbynumber_r <not supported> + getrpcbynumber_r <desired> <--- + ether_aton_r <not supported> + ether_ntoa_r <not supported> + __getnetgrent_r <not supported> + __internal_getnetgrent_r <not supported> + getnetgrent_r <not supported> + __getaliasent_r <not supported> + getaliasent_r <not supported> + __getaliasbyname_r <not supported> + getaliasbyname_r <not supported> + __nscd_getpwnam_r <not supported> + __nscd_getpwuid_r <not supported> + nscd_getpw_r <not supported> + __nscd_getgrgid_r <not supported> + __nscd_getgrnam_r <not supported> + nscd_getgr_r <not supported> + __nscd_gethostbyaddr_r <not supported> + __nscd_gethostbyname2_r <not supported> + __nscd_gethostbyname_r <not supported> + nscd_gethst_r <not supported> + __getutent_r <desired> <--- + getutent_r <desired> <--- + getutent_r_unknown <not supported> + getutid_r_unknown <not supported> + getutline_r_unknown <not supported> + __getutid_r <not supported> + getutid_r <desired> <--- + __getutline_r <not supported> + getutline_r <required> <--- + getutent_r_file <not supported> + getutid_r_file <not supported> + getutline_r_file <not supported> + internal_getut_r <not supported> + getutent_r_daemon <not supported> + getutid_r_daemon <not supported> + getutline_r_daemon <not supported> + __ptsname_r <not supported> + ptsname_r <not supported> + + +2.8 Additional thread-safe functions implemented by Proventhreads + + See description above. This applies only to the C library included + in the proventhreads distribution. + + inet_ntoa_r <desired> <--- + gethostbyaddr_r <desired> <--- + gethostbyname_r <desired> <--- + gethostent_r <not supported> + getnetbyaddr_r <desired> <--- + getnetbyname_r <desired> <--- + getnetent_r <desired> <--- + getprotobynumber_r <desired> <--- + getprotoent_r <desired> <--- + getprotobyname_r <desired> <--- + getservbyname_r <desired> <--- + getservbyport_r <desired> <--- + getservent_r <desired> <--- + + +3. List of functions in uClibc that use static data structures + + The following is a list of static data structures found in uClibc, + and the functions that use them. In most cases, static data is not + thread-safe, since multiple threads can access the same data at the + same time. This is an attempt to identify all of the static data that + is not considered thread-safe. Some of these problems will get + resolved by the changes outlines above. + + crypt/crypt.c: + + static struct crypt_data __crypt_data; + + crypt <crypt_r implemented> + setkey <setkey_r implemented> + encrypt <encrypt_r implemented> + + -------------------------------------------------------------------- + + crypt/md5.c: + + static unsigned char PADDING[64] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/addr.c: + + static char buf[16]; + + inet_ntoa <inet_ntoa_r not implemented> <--- + + -------------------------------------------------------------------- + + inet/getnetent.c: + + static FILE *netf = NULL; + static char line[BUFSIZ+1]; + static struct netent net; + static char *net_aliases[MAXALIASES]; + + setnetent <fix required> <--- + endnetent <fix required> <--- + getnetent <getnetent_r required> <--- + + NOTE: setnetent and endnetent are not implemented in glibc. + Proventhreads uses pthread mutexes to protect this static data. + + -------------------------------------------------------------------- + + inet/getproto.c: + + static FILE *protof = NULL; + static char line[BUFSIZ+1]; + static struct protoent proto; + static char *proto_aliases[MAXALIASES]; + static int proto_stayopen; + + setprotoent <fix required> <--- + endprotoent <fix required> <--- + getprotoent <getprotoent_r required> <--- + getprotobyname <getprotobyname_r required> <--- + getprotobynumber <getprotobynumber required> <--- + + NOTE: setprotoent and endprotoent are not implemented in glibc. + Proventhreads uses pthread mutexes to protect this static data. + + -------------------------------------------------------------------- + + inet/getservice.c: + + static FILE *servf = NULL; + static char line[BUFSIZ+1]; + static struct servent serv; + static char *serv_aliases[MAXALIASES]; + static int serv_stayopen; + + setservent <fix required> <--- + endservent <fix required> <--- + getservent <getservent_r required> <--- + getservbyname <getservbyname_r required> <--- + getservbyport <getservbyport_r required> <--- + + NOTE: setservent and endservent are not implemented in glibc. + Proventhreads uses pthread mutexes to protect this static data. + + -------------------------------------------------------------------- + + net/resolv.c: + + static int id = 1; + static int ns = 0; + + dns_lookup <fix required> <--- + + NOTE: dns_lookup is not implemented by glibc or Proventhreads. + + static struct hostent h; + static char namebuf[256]; + static struct in_addr in; + static struct in_addr *addr_list[2]; + + gethostbyname <gethostbyname_r required> <--- + + static struct hostent h; + static char namebuf[256]; + static struct in_addr in; + static struct in_addr *addr_list[2]; + + gethostbyaddr <gethostbyaddr_r required> <--- + + static struct hostent h; + static struct in_addr in; + static struct in_addr *addr_list[2]; + static char line[80]; + + read_etc_hosts <fix required> <--- + + NOTE: dns_lookup is not implemented by glibc or Proventhreads. + + -------------------------------------------------------------------- + + inet/rpc/auth_none.c: + + static struct auth_ops ops + static struct authnone_private + + authnone_create <fix required> <--- + authnone_marshal <fix required> <--- + + NOTE: This file makes a lot of use of this static variable and + also a global allocated authentication structure. Care should + be taken in fixing this to make it thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/auth_unix.c: + + static struct auth_ops auth_unix_ops + + authunix_create <fix required> <--- + marshal_new_auth <fix required> <--- + + NOTE: This file makes a lot of use of this static variable and + also a global allocated authentication structure. Care should + be taken in fixing this to make it thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/bindresvport.c: + + static short port; + + bindresvport <fix required> <--- + + -------------------------------------------------------------------- + + inet/rpc/clnt_perror.c: + + static char *buf; + static struct rpc_errtab rpc_errlist[] + static struct auth_errtab auth_errlist[] + + NOTE: These static structures all have #if 0 around them, so they + do not get compiled in. Hopefully, we don't have to worry about + them right now, but prehaps a comment should be added to the code + indicating that it is not thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/clnt_raw.c: + + static struct clntraw_private + static struct clnt_ops client_ops + + clntraw_create <fix required> <--- + clntraw_call <fix required> <--- + clntraw_freeres <fix required> <--- + + NOTE: This file makes a lot of use of these static variables and + also a global allocated client structure. Care should + be taken in fixing this to make it thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/clnt_simple.c: + + static struct callrpc_private + + callrpc <fix required> <--- + + -------------------------------------------------------------------- + + inet/rpc/clnt_tcp.c: + + static struct clnt_ops tcp_ops + + clnttcp_create + + NOTE: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/clnt_udp.c: + + static struct clnt_ops udp_ops + + clntudp_bufcreate + + NOTE: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/getrpcent.c: + + static char RPCDB[] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/pmap_clnt.c: + + static struct timeval timeout <fix desired> <--- + static struct timeval tottimeout <fix desired> <--- + + NOTE: These are okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/pmap_getport.c: + + static struct timeval timeout <fix desired> <--- + static struct timeval tottimeout <fix desired> <--- + + NOTE: These are okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/pmap_rmt.c: + + static struct timeval timeout <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/rpc_dtablesize.c: + + static int size; + + _rpc_dtablesize <fix required> <--- + + -------------------------------------------------------------------- + + inet/rpc/rpc_prot.c: + + static struct xdr_discrim reply_dscrm[3] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/svc.c: + + static SVCXPRT **xports; + static SVCXPRT *xports[NOFILE]; + static struct svc_callout + + xprt_register <fix required> <--- + xprt_unregister <fix required> <--- + svc_getreqset <fix required> <--- + svc_register <fix required> <--- + svc_unregister <fix required> <--- + svc_callout <fix required> <--- + + NOTE: This is intricate code, and care should be taken when making + this thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/svc_auth.c: + + static struct svcauthsw <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + -------------------------------------------------------------------- + + net/rpc/svc_raw.c: + + static struct svcraw_private + static struct xp_ops server_ops + + svcraw_create <fix required> <--- + svcraw_recv <fix required> <--- + svcraw_reply <fix required> <--- + svcraw_getargs <fix required> <--- + svcraw_freeargs <fix required> <--- + + NOTE: This is intricate code, and care should be taken when making + this thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/svc_simple.c: + + static struct proglst + static SVCXPRT *transp; + + registerrpc <fix required> <--- + universal <fix required> <--- + + NOTE: This is intricate code, and care should be taken when making + this thread-safe. + + -------------------------------------------------------------------- + + inet/rpc/svc_tcp.c: + + static struct xp_ops svctcp_op + static struct xp_ops svctcp_rendezvous_op + + svctcp_create <fix required> <--- + makefd_xprt <fix required> <--- + + NOTE: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + static struct timeval wait_per_try + + readtcp <fix required> <--- + + NOTE: This looks like a bug. This static timeout value is passed + by reference to a select() call. According to the linux man page + for select: + + "On Linux, timeout is modified to reflect the amount of + time not slept; most other implementations do not do this. + This causes problems both when Linux code which reads + timeout is ported to other operating systems, and when + code is ported to Linux that reuses a struct timeval for + multiple selects in a loop without reinitializing it. + Consider timeout to be undefined after select returns." + + Unless the implementation of select is different than that of Linux, + this needs to be fixed! + + -------------------------------------------------------------------- + + inet/rpc/svc_udp.c: + + static struct xp_ops svcudp_op <fix desired> (1) + + svcudp_bufcreate + + 1: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/xdr.c: + + static char xdr_zero[BYTES_PER_XDR_UNIT] <fix desired> <--- + + NOTE: This is okay, but should use the const keyword. + + static u_long crud[BYTES_PER_XDR_UNIT] + + NOTE: This looks like it doesn't matter what's in this array. + + -------------------------------------------------------------------- + + inet/rpc/xdr_float.c: + + static struct sgl_limits <fix desired> <--- + static struct dbl_limits <fix desired> <--- + + NOTE: These are okay, but should use the const keyword. + + -------------------------------------------------------------------- + + inet/rpc/xdr_mem.c: + + static struct xdr_ops xdrmem_ops <fix desired> (1) + + xdrmem_create + + 1: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/xdr_rec.c: + + static struct xdr_ops xdrrec_ops <fix desired> (1) + + xdrrec_create + + 1: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + inet/rpc/xdr_stdio.c: + + static struct xdr_ops xdrstdio_ops <fix desired> (1) + + xdrstdio_create + + 1: This static structure is just a group of function pointers. + It could probably be made const, but this might affect the function + signature. This should be investigated further. + + -------------------------------------------------------------------- + + ld.so-1/d-link/boot1.c: + + static char *_dl_malloc_addr + static char *_dl_mmap_zero + static char *_dl_not_lazy + static char *_dl_warn + static char *_dl_trace_loaded_objects + + _dl_boot <fix required> <--- + _dl_mall |