OSDN Git Service

Move the FAQ. Add a docs dir. Add in a report on thread support.
[uclinux-h8/uClibc.git] / docs / threads.txt
1 uClibc thread-safety analysis
2 By Steve Thayer <sthayer@coactive.com>
3 with updates by Erik Andersen <andersee@debian.org>
4
5 Introduction:
6
7 The purpose of this document is to identify the things that need to be done
8 to the uClibc C library in order to make it thread-safe.  The goal is to be
9 able to use a pthreads thread implementation under uClinux, using the uClibc
10 C library.  To help identify the things that require changing, I used David R.
11 Butenhof's book Programming With POSIX Threads, the source code for the
12 glibc 2.1.3 C library, and the source code for the C library included in the
13 Proventhreads distribution.
14
15 References:
16
17 Butenhof, David R., Programming With POSIX Threads,  Addison Wesley Longman, Inc., Reading, MA, ISBN 0-201-63392-2, 1997.
18
19
20 The GNU C library is available from the Free Software Foundation 
21 http://www.gnu.org/software/libc/libc.html
22
23 Proventhreads is part of the Inferno Operating system.
24 http://www.vitanuova.com/inferno/index.html
25
26
27 1. Stdio:
28
29 1.1 Buffer access mutexes
30
31         The following functions are required in order to protect shared
32         I/O buffers from being accessed by more than one thread at a time.
33         None of these functions are currently implemented in the uClibc
34         library, so they must be added.
35
36         flockfile               <required>                              <---
37         ftrylockfile            <required>                              <---
38         funlockfile             <required>                              <---
39
40 1.2 Functions that must use buffer access mutexes, according to Butenhof
41
42         The following functions are identified by Butenhof as needing to use
43         buffer access mutexes.  This does not represent all functions that
44         need to use the mutexes.
45
46         getc                    <mutex required>                        <---
47         getchar                 <mutex required>                        <---
48         putc                    <mutex required>                        <---
49         putchar                 <mutex required>                        <---
50
51 1.3 Functions from glibc (libio) that use buffer access mutexes
52
53         The following functions are functions found in glibc that currently
54         use the buffer access mutexes.  Comments in brackets represent
55         status of uClibc with regard to these functions.  Most of these
56         functions aren't even supported under uClibc, so no work is required.
57         The rest may require the access mutex. (These must be analyzed on a
58         case-by-case basis.)
59
60         clearerr                <mutex required>                        <---
61         feof                    <mutex required>                        <---
62         ferror                  <mutex required>                        <---
63         fputc                   <mutex required>                        <---
64         fputwc                  <not supported>
65         freopen                 <mutex required>                        <---
66         freopen64               <not supported>
67         fseek                   <mutex required>                        <---
68         fseeko                  <not supported>
69         fseeko64                <not supported>
70         ftello                  <not supported>
71         ftello64                <not supported>
72         fwide                   <not supported>
73         getc                    <macro for fgetc>
74         getchar                 <macro for fgetc>
75         getwc                   <not supported>
76         getwchar                <not supported>
77         iofclose                <not supported>
78         iofflush                <not supported>
79         iofgetpos               <not supported>
80         iofgetpos64             <not supported>
81         iofgets                 <not supported>
82         iofgetws                <not supported>
83         iofputs                 <not supported>
84         iofputws                <not supported>
85         iofread                 <not supported>
86         iofsetpos               <not supported>
87         iofsetpos64             <not supported>
88         ioftell                 <not supported>
89         iofwrite                <not supported>
90         iogetdelim              <not supported>
91         iogets                  <not supported>
92         ioputs                  <not supported>
93         ioseekoff               <not supported>
94         ioseekpos               <not supported>
95         iosetbuffer             <not supported>
96         iosetvbuf               <not supported>
97         ioungetc                <not supported>
98         ioungetwc               <not supported>
99         oldiofclose             <not supported>
100         oldiofgetpos            <not supported>
101         oldiofgetpos64          <not supported>
102         oldiofsetpos            <not supported>
103         oldiofsetpos64          <not supported>
104         peekc                   <not supported>
105         putc                    <macro for fputc>
106         putchar                 <macro for fputc>
107         putwc                   <not supported>
108         putwchar                <not supported>
109         rewind                  <mutex required>                        <---
110
111 1.4 Functions from Proventhreads that use buffer access mutexes
112
113         See description above.  This applies only to the C library included
114         in the proventhreads distribution.
115
116         clearerr                <mutex required>                        <---
117         fclose                  <mutex required>                        <---
118         fflush                  <mutex required>                        <---
119         fgetc                   <mutex required>                        <---
120         __getc                  <not supported>
121         fgetline                <not supported>
122         fgetpos                 <mutex required>                        <---
123         fgets                   <mutex required>                        <---
124         fpurge                  <not supported>
125         fputc                   <mutex required>                        <---
126         __putc                  <not supported>
127         fputs                   <mutex required>                        <---
128         fread                   <mutex required>                        <---
129         freopen                 <mutex required>                        <---
130         fscanf                  <mutex required>                        <---
131         fseek                   <mutex required>                        <---
132         ftell                   <mutex required>                        <---
133         fwalk                   <not supported>
134         fwrite                  <mutex required>                        <---
135         getc                    <macro for fgetc>
136         getchar                 <mutex required>                        <---
137         putc                    <macro for fputc>
138         putchar                 <mutex required>                        <---
139         puts                    <mutex required>                        <---
140         putw                    <not supported>
141         refill                  <not supported>
142         rewind                  <mutex required>                        <---
143         scanf                   <mutex required>                        <---
144         setvbuf                 <mutex required>                        <---
145         ungetc                  <mutex required>                        <---
146         vfprintf                <mutex required>                        <---
147         vscanf                  <mutex required>                        <---
148
149 1.5 Unlocked buffer access
150
151         These functions get used in situations where speed is important,
152         and locking isn't necessary, or for use in a section of code that
153         is already locked.  For example, a for-loop that makes multiple calls
154         to getc could make an exlicit call to flockfile outside the loop, and
155         then use getc_unlocked within the loop for speed.  That way, the lock
156         only needs to be grabbed and released once, rather than for each call.
157
158         getc_unlocked           <required>                              <---
159         getchar_unlocked        <required>                              <---
160         putc_unlocked           <required>                              <---
161         putchar_unlocked        <required>                              <---
162
163 1.6 Additional unlocked calls made in glibc
164
165         These are additional functions (not mentioned by Butenhof) that the
166         glibc library uses for unlocked buffer access.  Though not strictly
167         necessary, these may be nice to have in uClibc.
168
169         fileno_unlocked         <desired>                               <---
170         clearerr_unlocked       <desired>                               <---
171         feof_unlocked           <desired>                               <---
172         ferror_unlocked         <desired>                               <---
173         fputc_unlocked          <desired>                               <---
174         fgetc_unlocked          <desired>                               <---
175         fflush_unlocked         <desired>                               <---
176         fread_unlocked          <desired>                               <---
177         fwrite_unlocked         <desired>                               <---
178         fgets_unlocked          <desired>                               <---
179         fputs_unlocked          <desired>                               <---
180
181 1.7 Additional unlocked calls made in Proventhreads
182
183         Proventhreads only provides the four unlocked function calls above.
184
185         <none>
186
187
188 2. Thread-safe functions:
189
190         There are some functions in the C library standard that are
191         simply not thread-safe and cannot be thread-safe using their
192         current interface.  For example, any function that returns a
193         pointer to static data, or requires static context between
194         calls.  To resolve this problem, new functions were added to
195         the standard that perform the same basic task, but use a new
196         interface that does not require static data.  These functions
197         share their name with the old unsafe functions, but have an
198         "_r" appended to the name.  By definition, these functions are
199         reentrant and thread-safe.  It is important to note that these
200         functions to do not depend on <pthread.h> and can be used even
201         if threading is not supported.
202
203 2.1 User and terminal identification:
204
205         getlogin_r              <implemented>
206         ctermid                 <implemented>                           (1)
207         ttyname_r               <required>                              <---
208
209         1. ctermid is a special case.  The signature has not changed, but a
210         requirement has been added that its parameter point to a structure
211         of exactly L_ctermid bytes.  
212
213 2.2 Directory searching
214
215         readdir_r               <required>                              <---
216
217 2.3 String token
218
219         strtok_r                <implemented>
220
221 2.4 Time representation
222
223         asctime_r               <implemented>
224         ctime_r                 <implemented>
225         gmtime_r                <implemented>
226         localtime_r             <implemented>
227
228 2.5 Random number generation
229
230         rand_r                  <required>                              <---
231
232 2.6 Group and user database
233
234         getgrgid_r              <required>                              <---
235         getgrnam_r              <required>                              <---
236         getpwuid_r              <implemented>
237         getpwnam_r              <implemented>
238
239 2.7 Additional thread-safe functions implemented by glibc
240
241         The following is a list of additional functions implemented by glibc
242         that also provide thread-safe functionality.  Most of these functions
243         are not supported by uClibc, so there is no need to implement the
244         thread-safe version.  Those that do apply, but have not been
245         implemented yet are highlighted.
246
247         __fgetpwent_r                   <not supported>
248         fgetpwent_r                     <implemented>
249         __ttyname_r                     <not supported>
250         getttyname_r                    <not supported>
251         __getmntent_r                   <not supported>
252         getmntent_r                     <desired>                       <---
253         ecvt_r                          <not supported>
254         fcvt_r                          <not supported>
255         qecvt_r                         <not supported>
256         qfcvt_r                         <not supported>
257         hcreate_r                       <not supported>
258         hdestroy_r                      <not supported>
259         hsearch_r                       <not supported>
260         __getspent_r                    <not supported>
261         getspent_r                      <not supported>
262         __getspnam_r                    <not supported>
263         getspnam_r                      <not supported>
264         __sgetspent_r                   <not supported>
265         sgetspent_r                     <not supported>
266         __fgetspent_r                   <not supported>
267         fgetspent_r                     <not supported>
268         __gethostbyaddr_r               <not supported>
269         gethostbyaddr_r                 <desired>                       <---
270         __gethostbyname2_r              <not supported>
271         gethostbyname2_r                <not supported>
272         __gethostbyname_r               <not supported>
273         gethostbyname_r                 <desired>                       <---
274         __gethostent_r                  <not supported
275         gethostent_r                    <not supported>
276         __getnetbyaddr_r                <not supported>
277         getnetbyaddr_r                  <desired>                       <---
278         __getnetent_r                   <not supported>
279         getnetent_r                     <desired>                       <---
280         __getnetbyname_r                <not supported>
281         getnetbyname_r                  <desired>                       <---
282         __getprotobynumber_r            <not supported>
283         getprotobynumber_r              <desired>                       <---
284         __getprotoent_r                 <not supported>
285         getprotoent_r                   <desired>                       <---
286         __getprotobyname_r              <not supported>
287         getprotobyname_r                <desired>                       <---
288         __getservbyname_r               <not supported>
289         getservbyname_r                 <desired>                       <---
290         __getservbyport_r               <not supported>
291         getservbyport_r                 <desired>                       <---
292         __getservent_r                  <not supported>
293         getservent_r                    <desired>                       <---
294         __getrpcent_r                   <not supported>
295         getrpcent_r                     <desired>                       <---
296         __getrpcbyname_r                <not supported>
297         getrpcbyname_r                  <desired>                       <---
298         __getrpcbynumber_r              <not supported>
299         getrpcbynumber_r                <desired>                       <---
300         ether_aton_r                    <not supported>
301         ether_ntoa_r                    <not supported>
302         __getnetgrent_r                 <not supported>
303         __internal_getnetgrent_r        <not supported>
304         getnetgrent_r                   <not supported>
305         __getaliasent_r                 <not supported>
306         getaliasent_r                   <not supported>
307         __getaliasbyname_r              <not supported>
308         getaliasbyname_r                <not supported>
309         __nscd_getpwnam_r               <not supported>
310         __nscd_getpwuid_r               <not supported>
311         nscd_getpw_r                    <not supported>
312         __nscd_getgrgid_r               <not supported>
313         __nscd_getgrnam_r               <not supported>
314         nscd_getgr_r                    <not supported>
315         __nscd_gethostbyaddr_r          <not supported>
316         __nscd_gethostbyname2_r         <not supported>
317         __nscd_gethostbyname_r          <not supported>
318         nscd_gethst_r                   <not supported>
319         __getutent_r                    <desired>                       <---
320         getutent_r                      <desired>                       <---
321         getutent_r_unknown              <not supported>
322         getutid_r_unknown               <not supported>
323         getutline_r_unknown             <not supported>
324         __getutid_r                     <not supported>
325         getutid_r                       <desired>                       <---
326         __getutline_r                   <not supported>
327         getutline_r                     <required>                      <---
328         getutent_r_file                 <not supported>
329         getutid_r_file                  <not supported>
330         getutline_r_file                <not supported>
331         internal_getut_r                <not supported>
332         getutent_r_daemon               <not supported>
333         getutid_r_daemon                <not supported>
334         getutline_r_daemon              <not supported>
335         __ptsname_r                     <not supported>
336         ptsname_r                       <not supported>
337
338
339 2.8 Additional thread-safe functions implemented by Proventhreads
340
341         See description above.  This applies only to the C library included
342         in the proventhreads distribution.
343
344         inet_ntoa_r             <desired>                               <---
345         gethostbyaddr_r         <desired>                               <---
346         gethostbyname_r         <desired>                               <---
347         gethostent_r            <not supported>
348         getnetbyaddr_r          <desired>                               <---
349         getnetbyname_r          <desired>                               <---
350         getnetent_r             <desired>                               <---
351         getprotobynumber_r      <desired>                               <---
352         getprotoent_r           <desired>                               <---
353         getprotobyname_r        <desired>                               <---
354         getservbyname_r         <desired>                               <---
355         getservbyport_r         <desired>                               <---
356         getservent_r            <desired>                               <---
357
358
359 3. List of functions in uClibc that use static data structures
360
361         The following is a list of static data structures found in uClibc,
362         and the functions that use them.  In most cases, static data is not
363         thread-safe, since multiple threads can access the same data at the
364         same time.  This is an attempt to identify all of the static data that
365         is not considered thread-safe.  Some of these problems will get
366         resolved by the changes outlines above.
367
368         crypt/crypt.c:
369
370         static struct crypt_data __crypt_data;
371
372         crypt                   <crypt_r implemented>
373         setkey                  <setkey_r implemented>
374         encrypt                 <encrypt_r implemented>
375
376         --------------------------------------------------------------------
377
378         crypt/md5.c:
379
380         static unsigned char PADDING[64]        <fix desired>           <---
381
382         NOTE: This is okay, but should use the const keyword.
383
384         --------------------------------------------------------------------
385
386         inet/addr.c:
387
388         static char buf[16];
389
390         inet_ntoa               <inet_ntoa_r not implemented>           <---
391
392         --------------------------------------------------------------------
393
394         inet/getnetent.c:
395
396         static FILE *netf = NULL;
397         static char line[BUFSIZ+1];
398         static struct netent net;
399         static char *net_aliases[MAXALIASES];
400
401         setnetent               <fix required>                          <---
402         endnetent               <fix required>                          <---
403         getnetent               <getnetent_r required>                  <---
404
405         NOTE: setnetent and endnetent are not implemented in glibc.
406         Proventhreads uses pthread mutexes to protect this static data.
407
408         --------------------------------------------------------------------
409
410         inet/getproto.c:
411
412         static FILE *protof = NULL;
413         static char line[BUFSIZ+1];
414         static struct protoent proto;
415         static char *proto_aliases[MAXALIASES];
416         static int proto_stayopen;
417
418         setprotoent             <fix required>                          <---
419         endprotoent             <fix required>                          <---
420         getprotoent             <getprotoent_r required>                <---
421         getprotobyname          <getprotobyname_r required>             <---
422         getprotobynumber        <getprotobynumber required>             <---
423
424         NOTE: setprotoent and endprotoent are not implemented in glibc.
425         Proventhreads uses pthread mutexes to protect this static data.
426
427         --------------------------------------------------------------------
428
429         inet/getservice.c:
430
431         static FILE *servf = NULL;
432         static char line[BUFSIZ+1];
433         static struct servent serv;
434         static char *serv_aliases[MAXALIASES];
435         static int serv_stayopen;
436
437         setservent              <fix required>                          <---
438         endservent              <fix required>                          <---
439         getservent              <getservent_r required>                 <---
440         getservbyname           <getservbyname_r required>              <---
441         getservbyport           <getservbyport_r required>              <---
442
443         NOTE: setservent and endservent are not implemented in glibc.
444         Proventhreads uses pthread mutexes to protect this static data.
445
446         --------------------------------------------------------------------
447
448         net/resolv.c:   
449
450         static int id = 1;
451         static int ns = 0;
452
453         dns_lookup              <fix required>                          <---
454
455         NOTE: dns_lookup is not implemented by glibc or Proventhreads.
456
457         static struct hostent h;
458         static char namebuf[256];
459         static struct in_addr in;
460         static struct in_addr *addr_list[2];
461
462         gethostbyname           <gethostbyname_r required>              <---
463
464         static struct hostent h;
465         static char namebuf[256];
466         static struct in_addr in;
467         static struct in_addr *addr_list[2];
468
469         gethostbyaddr           <gethostbyaddr_r required>              <---
470
471         static struct hostent   h;
472         static struct in_addr   in;
473         static struct in_addr   *addr_list[2];
474         static char                             line[80];
475
476         read_etc_hosts          <fix required>                          <---
477
478         NOTE: dns_lookup is not implemented by glibc or Proventhreads.
479
480         --------------------------------------------------------------------
481
482         inet/rpc/auth_none.c:
483
484         static struct auth_ops ops
485         static struct authnone_private
486
487         authnone_create         <fix required>                          <---
488         authnone_marshal        <fix required>                          <---
489
490         NOTE: This file makes a lot of use of this static variable and
491         also a global allocated authentication structure.  Care should
492         be taken in fixing this to make it thread-safe.
493
494         --------------------------------------------------------------------
495
496         inet/rpc/auth_unix.c:
497
498         static struct auth_ops auth_unix_ops
499
500         authunix_create         <fix required>                          <---
501         marshal_new_auth        <fix required>                          <---
502
503         NOTE: This file makes a lot of use of this static variable and
504         also a global allocated authentication structure.  Care should
505         be taken in fixing this to make it thread-safe.
506
507         --------------------------------------------------------------------
508
509         inet/rpc/bindresvport.c:
510
511         static short port;
512
513         bindresvport            <fix required>                          <---
514
515         --------------------------------------------------------------------
516
517         inet/rpc/clnt_perror.c:
518
519         static char *buf;
520         static struct rpc_errtab rpc_errlist[]
521         static struct auth_errtab auth_errlist[]
522
523         NOTE: These static structures all have #if 0 around them, so they
524         do not get compiled in.  Hopefully, we don't have to worry about
525         them right now, but prehaps a comment should be added to the code
526         indicating that it is not thread-safe.
527
528         --------------------------------------------------------------------
529
530         inet/rpc/clnt_raw.c:
531
532         static struct clntraw_private
533         static struct clnt_ops client_ops
534         
535         clntraw_create          <fix required>                          <---
536         clntraw_call            <fix required>                          <---
537         clntraw_freeres         <fix required>                          <---
538
539         NOTE: This file makes a lot of use of these static variables and
540         also a global allocated client structure.  Care should
541         be taken in fixing this to make it thread-safe.
542
543         --------------------------------------------------------------------
544
545         inet/rpc/clnt_simple.c:
546
547         static struct callrpc_private
548
549         callrpc                 <fix required>                          <---
550         
551         --------------------------------------------------------------------
552
553         inet/rpc/clnt_tcp.c:
554
555         static struct clnt_ops tcp_ops
556
557         clnttcp_create
558
559         NOTE: This static structure is just a group of function pointers.
560         It could probably be made const, but this might affect the function
561         signature.  This should be investigated further.
562
563         --------------------------------------------------------------------
564
565         inet/rpc/clnt_udp.c:
566
567         static struct clnt_ops udp_ops
568
569         clntudp_bufcreate
570
571         NOTE: This static structure is just a group of function pointers.
572         It could probably be made const, but this might affect the function
573         signature.  This should be investigated further.
574
575         --------------------------------------------------------------------
576
577         inet/rpc/getrpcent.c:
578
579         static char RPCDB[]     <fix desired>                           <---
580
581         NOTE: This is okay, but should use the const keyword.
582
583         --------------------------------------------------------------------
584
585         inet/rpc/pmap_clnt.c:
586
587         static struct timeval timeout           <fix desired>           <---
588         static struct timeval tottimeout        <fix desired>           <---
589
590         NOTE: These are okay, but should use the const keyword.
591
592         --------------------------------------------------------------------
593
594         inet/rpc/pmap_getport.c:
595
596         static struct timeval timeout           <fix desired>           <---
597         static struct timeval tottimeout        <fix desired>           <---
598
599         NOTE: These are okay, but should use the const keyword.
600
601         --------------------------------------------------------------------
602
603         inet/rpc/pmap_rmt.c:
604
605         static struct timeval timeout           <fix desired>           <---
606
607         NOTE: This is okay, but should use the const keyword.
608
609         --------------------------------------------------------------------
610
611         inet/rpc/rpc_dtablesize.c:
612
613         static int size;
614
615         _rpc_dtablesize         <fix required>                          <---
616
617         --------------------------------------------------------------------
618
619         inet/rpc/rpc_prot.c:
620
621         static struct xdr_discrim reply_dscrm[3]        <fix desired>   <---
622
623         NOTE: This is okay, but should use the const keyword.
624
625         --------------------------------------------------------------------
626
627         inet/rpc/svc.c:
628
629         static SVCXPRT **xports;
630         static SVCXPRT *xports[NOFILE];
631         static struct svc_callout
632
633         xprt_register           <fix required>                          <---
634         xprt_unregister         <fix required>                          <---
635         svc_getreqset           <fix required>                          <---
636         svc_register            <fix required>                          <---
637         svc_unregister          <fix required>                          <---
638         svc_callout             <fix required>                          <---
639
640         NOTE: This is intricate code, and care should be taken when making
641         this thread-safe.
642
643         --------------------------------------------------------------------
644
645         inet/rpc/svc_auth.c:
646
647         static struct svcauthsw         <fix desired>                   <---
648
649         NOTE: This is okay, but should use the const keyword.
650
651         --------------------------------------------------------------------
652
653         net/rpc/svc_raw.c:      
654
655         static struct svcraw_private
656         static struct xp_ops server_ops
657
658         svcraw_create           <fix required>                          <---
659         svcraw_recv             <fix required>                          <---
660         svcraw_reply            <fix required>                          <---
661         svcraw_getargs          <fix required>                          <---
662         svcraw_freeargs         <fix required>                          <---
663
664         NOTE: This is intricate code, and care should be taken when making
665         this thread-safe.
666
667         --------------------------------------------------------------------
668
669         inet/rpc/svc_simple.c:
670
671         static struct proglst
672         static SVCXPRT *transp;
673
674         registerrpc             <fix required>                          <---
675         universal               <fix required>                          <---
676
677         NOTE: This is intricate code, and care should be taken when making
678         this thread-safe.
679
680         --------------------------------------------------------------------
681
682         inet/rpc/svc_tcp.c:
683
684         static struct xp_ops svctcp_op
685         static struct xp_ops svctcp_rendezvous_op
686
687         svctcp_create           <fix required>                          <---
688         makefd_xprt             <fix required>                          <---
689
690         NOTE: This static structure is just a group of function pointers.
691         It could probably be made const, but this might affect the function
692         signature.  This should be investigated further.
693
694         static struct timeval wait_per_try
695
696         readtcp                 <fix required>                          <---
697
698         NOTE: This looks like a bug.  This static timeout value is passed
699         by reference to a select() call.  According to the linux man page
700         for select:
701
702                 "On  Linux,  timeout  is  modified to reflect the amount of
703                 time not slept; most other implementations do not do this.
704                 This  causes  problems  both  when  Linux code which reads
705                 timeout is ported to other  operating  systems,  and  when
706                 code  is  ported to Linux that reuses a struct timeval for
707                 multiple selects in  a  loop  without  reinitializing  it.
708                 Consider timeout to be undefined after select returns."
709
710         Unless the implementation of select is different than that of Linux,
711         this needs to be fixed!
712
713         --------------------------------------------------------------------
714
715         inet/rpc/svc_udp.c:
716
717         static struct xp_ops svcudp_op          <fix desired>           (1)
718
719         svcudp_bufcreate
720
721         1: This static structure is just a group of function pointers.
722         It could probably be made const, but this might affect the function
723         signature.  This should be investigated further.
724
725         --------------------------------------------------------------------
726
727         inet/rpc/xdr.c: 
728
729         static char xdr_zero[BYTES_PER_XDR_UNIT]        <fix desired>   <---
730
731         NOTE: This is okay, but should use the const keyword.
732
733         static u_long crud[BYTES_PER_XDR_UNIT]
734
735         NOTE: This looks like it doesn't matter what's in this array.
736
737         --------------------------------------------------------------------
738
739         inet/rpc/xdr_float.c:
740
741         static struct sgl_limits        <fix desired>                   <---
742         static struct dbl_limits        <fix desired>                   <---
743
744         NOTE: These are okay, but should use the const keyword.
745
746         --------------------------------------------------------------------
747
748         inet/rpc/xdr_mem.c:
749
750         static struct xdr_ops xdrmem_ops        <fix desired>           (1)
751
752         xdrmem_create
753
754         1: This static structure is just a group of function pointers.
755         It could probably be made const, but this might affect the function
756         signature.  This should be investigated further.
757
758         --------------------------------------------------------------------
759
760         inet/rpc/xdr_rec.c:
761
762         static struct xdr_ops xdrrec_ops        <fix desired>           (1)
763
764         xdrrec_create
765
766         1: This static structure is just a group of function pointers.
767         It could probably be made const, but this might affect the function
768         signature.  This should be investigated further.
769
770         --------------------------------------------------------------------
771
772         inet/rpc/xdr_stdio.c:
773
774         static struct xdr_ops xdrstdio_ops      <fix desired>           (1)
775
776         xdrstdio_create
777
778         1: This static structure is just a group of function pointers.
779         It could probably be made const, but this might affect the function
780         signature.  This should be investigated further.
781
782         --------------------------------------------------------------------
783
784         ld.so-1/d-link/boot1.c:
785
786         static char *_dl_malloc_addr
787         static char *_dl_mmap_zero
788         static char *_dl_not_lazy
789         static char *_dl_warn
790         static char *_dl_trace_loaded_objects
791
792         _dl_boot                <fix required>                          <---
793         _dl_malloc              <fix required>                          <---
794         _dl_fixup               <fix required>                          <---
795
796         These are all part of the shared library loader, and are not
797         used by applications directly.  Therefore, fixing these is not 
798         a high priority item. 
799         
800         --------------------------------------------------------------------
801
802         ld.so-1/d-link/readelflib1.c:
803
804         static caddr_t _dl_cache_addr
805         static size_t _dl_cache_size
806
807         _dl_map_cache           <fix required>                          <---
808         _dl_unmap_cache         <fix required>                          <---
809         _dl_load_shared_library <fix required>                          <---
810         
811         These are all part of the shared library loader, and are not
812         used by applications directly.  Therefore, fixing these is not 
813         a high priority item. 
814         
815         --------------------------------------------------------------------
816
817         ld.so-1/d-link/string.h:
818
819         static char local[22]
820
821         _dl_simple_ltoa         <fix required>                          <---
822         _dl_simple_ltoahex      <fix required>                          <---
823
824         These are all part of the shared library loader, and are not
825         used by applications directly.  Therefore, fixing these is not 
826         a high priority item. 
827
828         --------------------------------------------------------------------
829
830         ld.so-1/d-link/arm/elfinterp.c:
831
832         static char *_dl_reltypes[]     <fix desired>                   <---
833
834         NOTE: This is okay, but should use the const keyword.
835
836         --------------------------------------------------------------------
837
838         ld.so-1/d-link/i386/elfinterp.c:
839
840         static char *_dl_reltypes[]     <fix desired>                   <---
841
842         NOTE: This is okay, but should use the const keyword.
843         
844         These are all part of the shared library loader, and are not
845         used by applications directly.  Therefore, fixing these is not 
846         a high priority item. 
847
848         --------------------------------------------------------------------
849
850         ld.so-1/d-link/m68k/elfinterp.c:
851
852         static char *_dl_reltypes[]     <fix desired>                   <---
853
854         NOTE: This is okay, but should use the const keyword.
855
856         These are all part of the shared library loader, and are not
857         used by applications directly.  Therefore, fixing these is not 
858         a high priority item. 
859
860         --------------------------------------------------------------------
861
862         ld.so-1/d-link/sparc/elfinterp.c:
863
864         static char *_dl_reltypes[]     <fix desired>                   <---
865
866         NOTE: This is okay, but should use the const keyword.
867
868         These are all part of the shared library loader, and are not
869         used by applications directly.  Therefore, fixing these is not 
870         a high priority item. 
871
872         --------------------------------------------------------------------
873
874         ld.so-1/libdl/dlib.c:
875
876         static int dl_init
877
878         _dlopen                 <fix required>                          <---
879
880         static int __attribute__ ((unused)) foobar1     <fix required?> (1)
881
882         NOTE: The comment for this says it all: "This is a real hack." ;-)
883         
884
885         static char *type[]     <fix desired>                           <---
886
887         NOTE: This is okay, but should use the const keyword.
888
889         These are all part of the shared library loader, and are not
890         used by applications directly.  Therefore, fixing these is not 
891         a high priority item. 
892
893         --------------------------------------------------------------------
894
895         ld.so-1/util/ldconfig.c:
896
897         static header_t magic   <fix desired>                           <---
898
899         NOTE: This is okay, but should use the const keyword.
900
901         static liblist_t *lib_head
902
903         cache_dolib             <fix required>                          <---
904         cache_write             <fix required>                          <---
905         
906         This is not actually part of the C library, and is not built by
907         default, so fixing these is not a high priority item. 
908
909         --------------------------------------------------------------------
910
911         misc/internals/tempname.c:
912
913         static uint64_t value;
914
915         __gen_tempname          <fix required>                          <---
916
917         --------------------------------------------------------------------
918
919         misc/locale/locale.c:
920
921         static char C_LOCALE_NAME[]="C";        <fix desired>           <---
922
923         NOTE: This is okay, but should use the const keyword.
924
925         static struct SAV_LOADED_LOCALE sav_loaded_locale [1]
926         static struct SAV_LOADED_LOCALE * old_locale
927
928         setlocale               <fix required>                          <---
929
930         NOTE: Can different threads use different locales?  I don't see
931         why not.
932
933         --------------------------------------------------------------------
934
935         misc/locale/localeconv.c:
936
937         static struct lconv result;
938
939         localeconv              <fix required>                          <---
940
941         NOTE: This function returns a pointer to a static data structure.
942
943         static char *blank = "";        <fix desired>                   <---
944         static char *decimal = ".";     <fix desired>                   <---
945
946         NOTE: These are okay, but should use the const keyword.
947
948         --------------------------------------------------------------------
949
950         misc/mntent/mntent.c:
951
952         static char buff[MNTMAXSTR];
953         static struct mntent mnt;
954
955         getmntent               <getmntent_r required>                  <---
956
957         --------------------------------------------------------------------
958
959         misc/regex/regex.c:
960
961         static char re_syntax_table[CHAR_SET_SIZE];
962         static int done = 0;
963
964         init_syntax_table       <fix required>                          <---
965
966         static int debug;
967
968         <several functions>     <fix required>                          <---
969
970         NOTE: This is used to turn on debugging, and is used in several
971         functions.  It will need to be fixed if you want differing debug
972         levels per thread.
973
974         static char reg_unset_dummy;
975
976         <REG_UNSET...>          <fix required>                          <---
977
978         static fail_stack_type fail_stack;
979
980         regex_compile           <fix required>                          <---
981         <FREE_VARIABLES>        <fix required>                          <---
982         <FAIL_STACK_EMPTY>      <fix required>                          <---
983         <FAIL_STACK_PTR_EMPTY>  <fix required>                          <---
984         <FAIL_STACK_FULL>       <fix required>                          <---
985         <INIT_FAIL_STACK>       <fix required>                          <---
986         <RESET_FAIL_STACK>      <fix required>                          <---
987         <DOUBLE_FAIL_STACK>     <fix required>                          <---
988         <PUSH_FAILURE_POINTER>  <fix required>                          <---
989         <PUSH_FAILURE_INT>      <fix required>                          <---
990         <PUSH_FAILURE_ELT>      <fix required>                          <---
991         <POP_FAILURE_POINTER>   <fix required>                          <---
992         <POP_FAILURE_INT>       <fix required>                          <---
993         <POP_FAILURE_ELT>       <fix required>                          <---
994         <REMAINING_AVAIL_SLOTS> <fix required>                          <---
995
996         static int regs_allocated_size;
997
998         regs_grow_registers     <fix required>                          <---
999
1000         static register_info_type *reg_info;
1001         static register_info_type *reg_info_dummy;
1002         static unsigned failure_id;
1003         static struct re_pattern_buffer re_comp_buf;
1004
1005         <too many to list>      <fix required>                          <---
1006         
1007         NOTE: This is just a NASTY file for static variables.  A lot of
1008         work needs to be done here to clean this up.  But I'm not even
1009         sure if it matters.  This code is taken directly from glibc.
1010
1011         This code is also very large (adds over 30k to the C library
1012         all by itself).  This file needs a complete rewrite.
1013
1014         --------------------------------------------------------------------
1015
1016         misc/syslog/syslog.c:
1017
1018         static pthread_once__t _once_block = pthread_once_init;
1019         static pthread_mutex_t _syslog_mutex;
1020         
1021         NOTE: I think these are okay. ;-)
1022
1023         static int LogFile = -1;
1024         static int connected;
1025         static int LogStat = 0;
1026         static int LogFacility = LOG_USER;
1027         static int LogMask = 0xff;
1028         static char truncate_msg[12]
1029         static struct sockaddr SyslogAddr;
1030
1031         NOTE: These are already protected.
1032
1033         --------------------------------------------------------------------
1034
1035         misc/time/asctime.c:
1036
1037         static char timebuf[26];
1038
1039         asctime                 <asctime_r implemented>
1040
1041         --------------------------------------------------------------------
1042
1043         misc/time/ctime.c:
1044
1045         static char cbuf[26];
1046
1047         ctime                   <ctime_r implemented>
1048
1049         --------------------------------------------------------------------
1050
1051         misc/time/gmtime.c:
1052
1053         static struct tm tmb;
1054
1055         gmtime                  <gmtime_r implemented>
1056
1057         --------------------------------------------------------------------
1058
1059         misc/time/localtime.c:
1060
1061         static struct tm tmb;
1062
1063         localtime               <localtime_r implemented>
1064
1065         --------------------------------------------------------------------
1066
1067         misc/time/mktime.c:
1068
1069         static tz_rule tz_rules[2];
1070
1071         tzset                   <fix required>                          <---
1072
1073         static time_t localtime_offset;
1074
1075         mktime                  <fix required>                          <---
1076
1077         --------------------------------------------------------------------
1078
1079         misc/time/tm_conv.c:
1080
1081         static int moffset[]    <fix desired>                           <---
1082         
1083         NOTE: This is okay, but should use the const keyword.
1084
1085         --------------------------------------------------------------------
1086
1087         misc/utmp/utent.c:
1088
1089         static int ut_fd = -1;
1090
1091         setutent                <fix required>                          <---
1092         endutent                <fix required>                          <---
1093         getutent                <fix required>                          <---
1094         getutid                 <fix required>                          <---
1095         getutline               <fix required>                          <---
1096         pututline               <fix required>                          <---
1097         utmpname                <fix required>                          <---
1098         
1099         static struct utmp utmp;
1100
1101         __getutent              <fix required>                          <---
1102
1103         --------------------------------------------------------------------
1104
1105         pwd_grp/__getgrent.c:
1106
1107         static char line_buff[GR_MAX_LINE_LEN];
1108         static char *members[GR_MAX_MEMBERS];
1109         static char *line_buff = NULL;
1110         static char **members = NULL;
1111         static struct group group;
1112
1113         __getgrent              <fix required>                          <---
1114
1115         --------------------------------------------------------------------
1116
1117         pwd_grp/fgetpwent.c:
1118
1119         static char line_buff[PWD_BUFFER_SIZE];
1120         static struct passwd pwd;
1121
1122         fgetpwent               <fgetpwent_r implemented>
1123
1124         --------------------------------------------------------------------
1125
1126         pwd_grp/getpwnam.c:
1127
1128         static char line_buff[PWD_BUFFER_SIZE];
1129         static struct passwd pwd;
1130
1131         getpwnam                <getpwnam_r implemented>
1132
1133         --------------------------------------------------------------------
1134
1135         pwd_grp/getpwuid.c:
1136
1137         static char line_buff[PWD_BUFFER_SIZE];
1138         static struct passwd pwd;
1139
1140         getpwuid                <getpwuid_r implemented>
1141
1142         --------------------------------------------------------------------
1143
1144         pwd_grp/grent.c:
1145
1146         static int grp_fd = -1;
1147
1148         setgrent                <fix required>                          <---
1149         endgrent                <fix required>                          <---
1150         getgrent                <fix required>                          <---
1151
1152         --------------------------------------------------------------------
1153
1154         pwd_grp/pwent.c:
1155
1156         static int pw_fd = -1;
1157
1158         setpwent                <fix required>                          <---
1159         endpwent                <fix required>                          <---
1160         getpwent_r              <fix required>                          <---
1161
1162         NOTE: Yeah, this looks weird, but getpwent_r isn't completely
1163         thread-safe.
1164
1165         static char line_buff[PWD_BUFFER_SIZE]; 
1166         static struct passwd pwd;
1167
1168         getpwent                <getpwent_r implemented>                <---
1169
1170         --------------------------------------------------------------------
1171
1172         stdio/tmpnam.c:
1173
1174         static char tmpnam_buffer[L_tmpnam];
1175
1176         tmpnam                  <tmpnam_r implemented>
1177
1178         --------------------------------------------------------------------
1179
1180         stdlib/atexit.c:
1181
1182         static vfuncp __atexit_table[__UCLIBC_MAX_ATEXIT];
1183         static int __atexit_count = 0;
1184
1185         atexit_handler          <fix required>                          <---
1186         atexit                  <fix required>                          <---
1187
1188         --------------------------------------------------------------------
1189
1190         stdlib/bsearch.c:
1191
1192         static int _bsearch;
1193
1194         bsearch                 <fix required>                          <---
1195
1196         --------------------------------------------------------------------
1197
1198         stdlib/putenv.c:
1199
1200         static char **mall_env = 0;
1201         static int extras = 0;
1202
1203         putenv                  <fix required>                          <---
1204
1205         --------------------------------------------------------------------
1206
1207         stdlib/random.c:
1208
1209         static long int seed1 = 1;
1210         static long int seed2 = 1;
1211         static long int seed3 = 1;
1212
1213         random                  <fix required?>                         (1)
1214         srandom                 <fix required?>                         (1)
1215
1216         1: I'm not sure if it matters if these are static, since they
1217         are random number seeds.  Who cares if more than one thread changes
1218         their value?
1219
1220         --------------------------------------------------------------------
1221
1222         stdlib/setenv.c:
1223
1224         static pthread_once__t _once_block = pthread_once_init;         (1)
1225         static pthread_mutex_t _setenv_mutex;                           (1)
1226         static char **last_environ = NULL;                              (1)
1227
1228         1: Obviously, nothing to do here. (Unless I change the way we
1229         deal with threads).
1230
1231         --------------------------------------------------------------------
1232
1233         stdlib/malloc/avlmacro.h
1234
1235         static objname *__Avl_##objname##pr##_new_node;
1236
1237         Avl_Tree_no_replace     <fix required>                          <---
1238
1239         NOTE: This will take a bit of study to figure out if it needs fixing.
1240
1241         --------------------------------------------------------------------
1242
1243         stdlib/malloc/malloc.c:
1244
1245         //static mutex_t malloc_lock = MUTEX_INITIALIZER;               <---
1246
1247         NOTE: Basically, thread support in malloc is broken and must be
1248         fixed.  It looks like the infrastructure is there, but more
1249         investigation is required.
1250
1251         --------------------------------------------------------------------
1252
1253         stdlib/malloc-930716/malloc.c:
1254
1255         static int heapsize;
1256         static int initialized;
1257         static size_t pagesize;
1258         
1259         inititalize             <fix required>                          <---
1260         morecore                <fix required>                          <---
1261         malloc                  <fix required>                          <---
1262
1263         --------------------------------------------------------------------
1264
1265         stdlib/malloc-930716/valloc.c:
1266
1267         static size_t pagesize;
1268
1269         valloc                  <fix required>                          <---
1270
1271         --------------------------------------------------------------------
1272
1273         string/config.c:
1274
1275         static char *args[16];
1276         static char cfgbuf[128];
1277
1278         cfgread                 <fix required>                          <---
1279
1280         --------------------------------------------------------------------
1281
1282         string/strerror.c:
1283
1284         static char retbuf[48];
1285         static char retbuf[33];
1286
1287         strerror                <fix required>                          <---
1288         main                    <fix required>                          <---
1289
1290         --------------------------------------------------------------------
1291
1292         string/strsignal.c:
1293
1294         static char retbuf[28];
1295
1296         strsignal               <fix required>                          <---
1297         main                    <fix required>                          <---
1298
1299         --------------------------------------------------------------------
1300
1301         string/strtok.c:
1302
1303         static char *save = 0;
1304
1305         strtok                  <strtok_r implemented>                  <---
1306
1307         --------------------------------------------------------------------
1308
1309         sysdeps/linux/common/kernel_version.c:
1310
1311         static int __linux_kernel_version = -1;
1312
1313         __get_linux_kernel_version      <fix required>                  (1)
1314
1315         1: This static value never actually gets updated!  This a bug.
1316
1317         --------------------------------------------------------------------
1318
1319         sysdeps/linux/i386/bits/huge_val.h:
1320
1321         static __huge_val_t __huge_val          <fix desired>           <---
1322         static __huge_valf_t __huge_valf        <fix desired>           <---
1323         static __huge_vall_t __huge_vall        <fix desired>           <---
1324
1325         NOTE: These are okay, but should use the const keyword.
1326
1327         --------------------------------------------------------------------
1328
1329         sysdeps/linux/i386/bits/nan.h:
1330
1331         static union { ... } __nan_union        <fix desired>           <---
1332
1333         NOTE: This is okay, but should use the const keyword.
1334
1335         --------------------------------------------------------------------
1336
1337         sysdeps/linux/m68k/bits/huge_val.h:
1338
1339         static union { ... } __huge_val         <fix desired>           <---
1340         static union { ... } __huge_valf        <fix desired>           <---
1341         static union { ... } __huge_vall        <fix desired>           <---
1342
1343         NOTE: These are okay, but should use the const keyword.
1344
1345         --------------------------------------------------------------------
1346
1347         sysdeps/linux/m68k/bits/nan.h:
1348
1349         static union { ... } __nan_union        <fix desired>           <---
1350
1351         NOTE: This is okay, but should use the const keyword.
1352
1353         --------------------------------------------------------------------
1354
1355         sysdeps/linux/sh/bits/huge_val.h:
1356
1357         static __huge_val_t __huge_val          <fix desired>           <---
1358         static __huge_valf_t __huge_valf        <fix desired>           <---
1359
1360         NOTE: These are okay, but should use the const keyword.
1361
1362         --------------------------------------------------------------------
1363
1364         sysdeps/linux/sh/bits/nan.h:
1365
1366         static union { ... } __nan_union        <fix desired>           <---
1367
1368         NOTE: This is okay, but should use the const keyword.
1369
1370         --------------------------------------------------------------------
1371
1372         sysdeps/linux/sparc/bits/huge_val.h:
1373
1374         static __huge_val_t __huge_val          <fix desired>           <---
1375         static __huge_valf_t __huge_valf        <fix desired>           <---
1376
1377         NOTE: These are okay, but should use the const keyword.
1378
1379         --------------------------------------------------------------------
1380
1381         sysdeps/linux/sparc/bits/nan.h:
1382
1383         static union { ... } __nan_union        <fix desired>           <---
1384
1385         NOTE: This is okay, but should use the const keyword.
1386
1387         --------------------------------------------------------------------
1388
1389         termios/tcgetsid.c:
1390
1391         static int tiocgsid_does_not_work;
1392
1393         tcgestsid               <fix required>                          <---
1394
1395         --------------------------------------------------------------------
1396
1397         termios/ttyname.c:
1398
1399         static char dev[] = "/dev";
1400
1401         ttyname                 <fix desired>                           <---
1402
1403         NOTE: This is okay, but should use the const keyword.
1404
1405         static char name[NAME_MAX];
1406
1407         ttyname                 <ttyname_r required>                    <---
1408
1409         --------------------------------------------------------------------
1410
1411         test/testsuite.h:
1412
1413         static int failures
1414
1415         error_msg               <fix required>                          <---
1416         done_testing            <fix required>                          <---
1417         init_testsuite          <fix required>                          <---
1418         
1419         --------------------------------------------------------------------
1420
1421         unistd/getcwd.c:
1422
1423         static char *path_buf;
1424         static int path_size;
1425         static dev_t root_dev;
1426         static ino_t root_ino;
1427         static struct stat st;
1428
1429         getswd                  <fix required>                          <---
1430         recurser                <fix required>                          <---
1431         search_dir              <fix required>                          <---
1432         
1433         --------------------------------------------------------------------
1434
1435         unistd/getopt.c:
1436
1437         static int sp = 1;
1438
1439         getopt                  <fix required>                          <---
1440         
1441         --------------------------------------------------------------------
1442
1443         unistd/getpass.c:
1444
1445         static char buf[PWD_BUFFER_SIZE];
1446
1447         getpass                 <fix required>                          <---
1448         
1449         NOTE: This function returns a pointer to a static data structure.
1450         This seems like it requires an _r version of this function.  Glibc
1451         does the same thing.  Oops!  So much for thread-safe glibc!
1452
1453         --------------------------------------------------------------------
1454
1455         unistd/gnu_getopt.c:
1456
1457         static char *nextchar;
1458         static enum ordering;
1459         static int first_nonopt;
1460         static int last_nonopt;
1461
1462         _getopt_initialize      <fix required>                          <---
1463         _getopt_internal        <fix required>                          <---
1464         exchange                <fix required>                          <---
1465
1466         static struct option long_options[]     <fix desired>           <---
1467
1468         NOTE: This is okay, but should use the const keyword.
1469
1470         --------------------------------------------------------------------
1471
1472         unistd/sysconf.c:
1473
1474         static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS];
1475
1476         find_or_add_in_table    <fix required?>                         <---
1477         main                    <fix required?>                         <---
1478
1479         NOTE: I'm not sure if this needs to be multi-threaded or not.
1480
1481         --------------------------------------------------------------------
1482
1483         unistd/sysconf_src.c:
1484
1485         static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS];
1486
1487         find_or_add_in_table    <fix required?>                         <---
1488         main                    <fix required?>                         <---
1489
1490         NOTE: I'm not sure if this needs to be multi-threaded or not.
1491
1492         --------------------------------------------------------------------
1493
1494         unistd/sysconf_i386.c:
1495
1496         static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS];
1497
1498         find_or_add_in_table    <fix required?>                         <---
1499         main                    <fix required?>                         <---
1500
1501         NOTE: I'm not sure if this needs to be multi-threaded or not.
1502
1503         --------------------------------------------------------------------
1504
1505
1506 4. List of functions that use global variables
1507
1508         The following is a list of functions that make use of global
1509         variables.  Since multiple threads can access the same global
1510         variable at the same time, access should be considered unsafe.
1511         This is an attempt to identify all the areas where global
1512         variables are used.  This does not necessarily mean that each
1513         of these is unsafe.  It just means that there is a potential
1514         for them to be unsafe.  If this code never runs in more than
1515         one thread, then there's no problem.  More ivestigation will be
1516         required to determine if changes are really required.
1517
1518         Global variable:
1519
1520         __environ (misc/internals/__uClibc_main.c)
1521
1522         __uClibc_main.c:
1523
1524         __uClibc_main           <fix required?>                         (1)
1525
1526         1: This should only get executed once, so it is probably fine.
1527         
1528         stdlib/getenv.c:
1529
1530         getenv                  <fix required>                          <---
1531
1532         stdlib/putenv.c:
1533
1534         putenv                  <fix required>                          <---
1535
1536         stdlib/setenv.c:
1537
1538         setenv                  <fix required>                          <---
1539         unsetenv                <fix required>                          <---
1540
1541         test/args/arg_test.c:
1542
1543         main                    <fix required>                          <---
1544
1545         unistd/execl.c:
1546
1547         execl                   <fix required>                          <---
1548
1549         unistd/execlp.c:
1550
1551         execlp                  <fix required>                          <---
1552
1553         unistd/execv.c:
1554
1555         execv                   <fix required>                          <---
1556
1557         unistd/execvp.c:
1558
1559         execvep                 <fix required>                          <---
1560
1561         --------------------------------------------------------------------
1562
1563         Global variable:
1564
1565         __uClibc_cleanup (misc/internals/__uClibc_main.c)
1566
1567         stdlib/abort.c:
1568
1569         abort                   <fix required>                          <---
1570
1571         stdlib/atexit.c:
1572
1573         atexit_handler          <fix required>                          <---
1574         atexit                  <fix required>                          <---
1575         exit                    <fix required>                          <---
1576
1577         NOTE: Not sure if multiple threads can be in this code or not.
1578
1579         --------------------------------------------------------------------
1580
1581         Global variable:
1582
1583         environ (misc/internals/__uClibc_main.c)
1584
1585         NOTE: This is a weak alias for __environ, but it doesn't ever get
1586         used in the uClibc library.
1587
1588         --------------------------------------------------------------------
1589
1590         Global variable:
1591
1592         timezone (misc/time/tm_conv.c)
1593
1594         misc/time/tm_conv.c:
1595
1596         __tm_conv               <fix required>                          <---
1597
1598         --------------------------------------------------------------------
1599
1600         Global variable:
1601
1602         re_max_failures (misc/regex/regex.c)
1603
1604         misc/regex/regex.c:
1605
1606         DOUBLE_FAIL_STACK       <fix required>                          <---
1607         regex_compile           <fix required>                          <---
1608
1609         --------------------------------------------------------------------
1610
1611         Global variable:
1612
1613         re_syntax_options (misc/regex/regex.c)
1614
1615         misc/regex/regex.c:
1616
1617         re_set_syntax           <fix required>                          <---
1618         re_compile_pattern      <fix required>                          <---
1619         re_comp                 <fix required>                          <---
1620
1621         --------------------------------------------------------------------
1622
1623         Global variable:
1624
1625         __IO_list (stdio/stdio.c)
1626
1627         stdio/stdio.c:
1628
1629         fflush                  <fix required>                          <---
1630         __fopen                 <fix required>                          <---
1631         fclose                  <fix required>                          <---
1632
1633         --------------------------------------------------------------------
1634
1635         Global variable:
1636
1637         _fixed_buffers (stdio/stdio.c)
1638
1639         stdio/stdio.c:
1640
1641         _alloc_stdio_buffer             <fix required>                  <---
1642         _free_stdio_buffer_of_file      <fix required>                  <---
1643         __init_stdio                    <fix required>                  <---
1644         
1645         --------------------------------------------------------------------
1646
1647         Global variable:
1648
1649         _free_buffer_index (stdio/stdio.c)
1650
1651         stdio/stdio.c:
1652
1653         _alloc_stdio_buffer             <fix required>                  <---
1654         _free_stdio_buffer_of_file      <fix required>                  <---
1655         __init_stdio                    <fix required>                  <---
1656
1657         --------------------------------------------------------------------
1658
1659         Global variable:
1660
1661         _free_file_list (stdio/stdio.c)
1662
1663         stdio/stdio.c:
1664
1665         __init_stdio            <fix required>                          <---
1666         _alloc_stdio_stream     <fix required>                          <---
1667         _free_stdio_stream      <fix required>                          <---
1668
1669         --------------------------------------------------------------------
1670
1671         Global variable:
1672
1673         _stderr (stdio/stdio.c)
1674
1675         ld.so-1/util/ldconfig.c:
1676
1677         warn                    <fix required>                          <---
1678         error                   <fix required>                          <---
1679         usage                   <fix required>                          <---
1680
1681         ld.so-1/util/ldd.c:
1682
1683         warn                    <fix required>                          <---
1684         error                   <fix required>                          <---
1685         is_bin                  <fix required>                          <---
1686         main                    <fix required>                          <---
1687         
1688         misc/locale/locale.c:
1689
1690         setlocale               <fix required>                          <---
1691         
1692         misc/regex/regex.c:
1693
1694         printchar               <fix required>                          <---
1695
1696         stdio/perror.c:
1697
1698         perror                  <fix required>                          <---
1699
1700         stdlib/malloc/alloc.c:
1701
1702         calloc_dbg              <fix required>                          <---
1703         malloc_dbg              <fix required>                          <---
1704         free_dbg                <fix required>                          <---
1705
1706         stdlib/malloc/malloc.c:
1707
1708         __hunk_alloc            <fix required?>                         (1)
1709         __malloc_init           <fix required?>                         (1)
1710         malloc                  <fix required?>                         (1)
1711
1712         1: These are commented out with C++ style comments.
1713
1714         stdlib/malloc-simple/alloc.c:
1715
1716         calloc_dbg              <fix required>                          <---
1717         malloc_dbg              <fix required>                          <---
1718         free_dbg                <fix required>                          <---
1719
1720         string/strsignal.c:
1721
1722         psignal                 <fix required>                          <---
1723
1724         test/args/arg_test.c:
1725
1726         main                    <fix required>                          <---
1727
1728         test/assert/assert.c:
1729
1730         main                    <fix required>                          <---
1731
1732         unistd/getopt.c:
1733
1734         Err                     <fix required>                          <---
1735
1736         unistd/getpass.c:
1737
1738         getpass                 <fix required>                          <---
1739
1740         unistd/gnu_getopt.c:
1741
1742         _getopt_internal        <fix required>                          <---
1743
1744         unistd/sysconf.c:
1745
1746         main                    <fix required>                          <---
1747
1748         unistd/sysconf_src.c:
1749
1750         main                    <fix required>                          <---
1751
1752         unistd/sysconf_i386.c:
1753
1754         main                    <fix required>                          <---
1755
1756         --------------------------------------------------------------------
1757
1758         Global variable:
1759
1760         _stdin (stdio/stdio.c)
1761
1762         include/stdio.h:
1763
1764         getchar                 <fix required>                          <---
1765
1766         include/bits/stdio.h:
1767
1768         getchar                 <fix required>                          <---
1769         getchar_unlocked        <fix required>                          <---
1770
1771         stdio/scanf.c:
1772
1773         scanf                   <fix required>                          <---
1774         vscanf                  <fix required>                          <---
1775
1776         stdio/stdio.c
1777
1778         gets                    <fix required>                          <---
1779         getchar                 <fix required>                          <---
1780
1781         sysdeps/linux/i386/bits/stdio.h:
1782
1783         getchar                 <fix required>                          <---
1784         getchar_unlocked        <fix required>                          <---
1785
1786         sysdeps/linux/m68k/bits/stdio.h:
1787
1788         getchar                 <fix required>                          <---
1789         getchar_unlocked        <fix required>                          <---
1790
1791         sysdeps/linux/sh/bits/stdio.h:
1792
1793         getchar                 <fix required>                          <---
1794         getchar_unlocked        <fix required>                          <---
1795
1796         sysdeps/linux/sparc/bits/stdio.h:
1797
1798         getchar                 <fix required>                          <---
1799         getchar_unlocked        <fix required>                          <---
1800
1801         unistd/getpass.c:
1802
1803         getpass                 <fix required>                          <---
1804
1805         --------------------------------------------------------------------
1806
1807         Global variable:
1808
1809         _stdio_streams (stdio/stdio.c)
1810
1811         stdio/stdio.c:
1812
1813         __init_stdio            <fix required>                          <---
1814         _free_stdio_stream      <fix required>                          <---
1815
1816         --------------------------------------------------------------------
1817
1818         Global variable:
1819
1820         _stdout (stdio/stdio.c)
1821
1822         include/stdio.h:
1823
1824         putchar                 <fix required>                          <---
1825
1826         include/bits/stdio.h:
1827
1828         vprintf                 <fix required>                          <---
1829         putchar                 <fix required>                          <---
1830         putchar_unlocked        <fix required>                          <---
1831
1832         ld.so-1/util/ldconfig.c:
1833
1834         warn                    <fix required>                          <---
1835         error                   <fix required>                          <---
1836
1837         ld.so-1/util/ldd.c:
1838
1839         warn                    <fix required>                          <---
1840         error                   <fix required>                          <---
1841         main                    <fix required>                          <---
1842
1843         stdio/printf.c:
1844
1845         printf                  <fix required>                          <---
1846         vprintf                 <fix required>                          <---
1847
1848         stdio/stdio.c:
1849
1850         puts                    <fix required>                          <---
1851         _uClibc_fread           <fix required>                          <---
1852         putchar                 <fix required>                          <---
1853
1854         sysdeps/linux/i386/bits/stdio.h:
1855
1856         vprintf                 <fix required>                          <---
1857         putchar                 <fix required>                          <---
1858         putchar_unlocked        <fix required>                          <---
1859
1860         sysdeps/linux/m68k/bits/stdio.h:
1861
1862         vprintf                 <fix required>                          <---
1863         putchar                 <fix required>                          <---
1864         putchar_unlocked        <fix required>                          <---
1865
1866         sysdeps/linux/sh/bits/stdio.h:
1867
1868         vprintf                 <fix required>                          <---
1869         putchar                 <fix required>                          <---
1870         putchar_unlocked        <fix required>                          <---
1871
1872         sysdeps/linux/sparc/bits/stdio.h:
1873
1874         vprintf                 <fix required>                          <---
1875         putchar                 <fix required>                          <---
1876         putchar_unlocked        <fix required>                          <---
1877
1878         test/pwd_grp/test_grp.c:
1879
1880         main                    <fix required>                          <---
1881
1882         test/pwd_grp/test_pwd.c:
1883
1884         main                    <fix required>                          <---
1885
1886         --------------------------------------------------------------------
1887
1888         Global variable:
1889
1890         dns_caught_signal (inet/resolv.c)
1891
1892         inet/resolv.c:
1893
1894         dns_catch_signal        <fix required>                          <---
1895         dns_lookup              <fix required>                          <---
1896
1897         --------------------------------------------------------------------
1898
1899         Global variable:
1900
1901         nameserver (inet/resolv.c)
1902         nameservers (inet/resolv.c)
1903
1904         inet/resolv.c:
1905
1906         open_nameservers        <fix required>                          <---
1907         close_nameservers       <fix required>                          <---
1908         resolve_name            <fix required>                          <---
1909         gethostbyname           <fix required>                          <---
1910         res_query               <fix required>                          <---
1911         gethostbyaddr           <fix required>                          <---
1912         
1913         --------------------------------------------------------------------
1914
1915         Global variable:
1916
1917         searchdomain (inet/resolv.c)
1918         searchdomains (inet/resolv.c)
1919
1920         inet/resolv.c:
1921
1922         dns_lookup              <fix required>                          <---
1923         
1924         --------------------------------------------------------------------
1925
1926         Global variable:
1927
1928         _net_stayopen (inet/getnetent.c)
1929
1930         inet/getnetbyad.c:
1931
1932         getnetbyaddr            <fix required>                          <---
1933
1934         inet/getnetbynm.c:
1935
1936         getnetbyname            <fix required>                          <---
1937
1938         inet/getnetent.c:
1939
1940         setnetent               <fix required>                          <---
1941         endnetent               <fix required>                          <---
1942         
1943         --------------------------------------------------------------------
1944
1945         Global variable:
1946
1947         rpcdata (inet/rpc/getrpcent.c)
1948
1949         inet/rpc/getrpcent.c:
1950
1951         _rpcdata                <fix required>                          <---
1952
1953         --------------------------------------------------------------------
1954
1955         Global variable:
1956
1957         _null_auth (inet/rpc/rpc_commondata.c)  <fix desired>           <---
1958
1959         NOTE: _null_auth is never actually initialized.  It never gets written,
1960         only read.  So it should be thread safe.  But it should be declared
1961         as a const if that is the case.  It should also be initialized.
1962
1963         inet/rpc/auth_none.c:
1964
1965         authnone_create 
1966
1967         inet/rpc/auth_unix.c:
1968
1969         authunix_create
1970
1971         inet/rpc/clnt_raw.c:
1972
1973         clntraw_call
1974
1975         inet/rpc/clnt_tcp.c:
1976
1977         clnttcp_call
1978
1979         inet/rpc/clnt_udp.c:
1980
1981         clntudp_call
1982
1983         inet/rpc/pmap_rmt.c:
1984
1985         clnt_broadcast
1986
1987         inet/rpc/svc_auth.c:
1988
1989         _authenticate
1990
1991         inet/rpc/svc_tcp.c:
1992
1993         svctcp_create
1994
1995         --------------------------------------------------------------------
1996
1997         Global variable:
1998
1999         rpc_createerr (inet/rpc/rpc_commondata.c)
2000
2001         inet/rpc/clnt_generic.c:
2002
2003         clnt_create             <fix required>                          <---
2004         
2005         inet/rpc/clnt_perror.c:
2006
2007         clnt_spcreateerror      <fix desired?>                          <---
2008
2009         NOTE: This piece of code has an "#if 0" around it.
2010
2011         inet/rpc/clnt_simple.c:
2012
2013         callrpc                 <fix required>                          <---
2014
2015         inet/rpc/clnt_tcp.c:
2016
2017         clnttcp_create          <fix required>                          <---
2018
2019         inet/rpc/clnt_udp.c:
2020
2021         clntudp_bufcreate       <fix required>                          <---
2022
2023         inet/rpc/pmap_getport.c:
2024
2025         pmap_getport            <fix required>                          <---
2026
2027         --------------------------------------------------------------------
2028
2029         Global variable:
2030
2031         svc_fdset (inet/rpc/rpc_commondata.c)
2032
2033         inet/rpc/svc.c:
2034
2035         xprt_register           <fix required>                          <---
2036         xprt_unregister         <fix required>                          <---
2037         svc_getreq              <fix required>                          <---
2038
2039         inet/rpc/svc_run.c:
2040
2041         svc_run                 <fix required>                          <---
2042
2043         NOTE: Be careful to also fix the uses of the "svc_fds" #define.
2044
2045         --------------------------------------------------------------------
2046
2047         Global variable:
2048
2049         pl (inet/rpc/svc_simple.c)
2050
2051         registerrpc             <fix required>                          <---
2052
2053         NOTE: proglst is set up to point at pl, so it needs fixing as well.
2054         (See proglst earlier in this document.)
2055
2056         --------------------------------------------------------------------
2057
2058         Global variable:
2059
2060         _sigintr (signal/signal.c)
2061
2062         signal/bsd_sig.c:
2063
2064         __bsd_signal            <fix required>                          <---
2065
2066         signal/sigintr.c:
2067
2068         siginterrupt            <fix required>                          <---
2069
2070         --------------------------------------------------------------------
2071
2072         Global variable:
2073
2074         __Avl_Block_tfree_mem_tree (stdlib/malloc/malloc.c)
2075
2076         stdlib/malloc/malloc.c:
2077
2078         __free_mem_del_block    <fix required>                          <---
2079         bl_alloc                <fix required>                          <---
2080         __malloc_init           <fix required>                          <---
2081
2082         NOTE: This code is very tricky stuff.
2083
2084         --------------------------------------------------------------------
2085
2086         Global variable:
2087
2088         __Avl_Block_tptrs_tree (stdlib/malloc/malloc.c)
2089
2090         stdlib/malloc/malloc.c:
2091
2092         __bl_free               <fix required>                          <---
2093         __malloc_init           <fix required>                          <---
2094         free                    <fix required>                          <---
2095         _realloc_no_move        <fix required>                          <---
2096         realloc                 <fix required>                          <---
2097
2098         --------------------------------------------------------------------
2099
2100         Global variable:
2101
2102         __bl_last (stdlib/malloc/malloc.c)
2103
2104         stdlib/malloc/malloc.c:
2105
2106         COMBINE_BLOCKS          <fix required>                          <---
2107         SPLIT_BLOCK             <fix required>                          <---
2108         bl_mapnew               <fix required>                          <---
2109         bl_alloc                <fix required>                          <---
2110         __malloc_init           <fix required>                          <---
2111         
2112         --------------------------------------------------------------------
2113
2114         Global variable:
2115
2116         __free_h (stdlib/malloc/malloc.c)
2117
2118         stdlib/malloc/malloc.c:
2119
2120         __hunk_alloc            <fix required>                          <---
2121         __hunk_free             <fix required>                          <---
2122         __malloc_init           <fix required>                          <---
2123         
2124         --------------------------------------------------------------------
2125
2126         Global variable:
2127
2128         __malloc_initialized (stdlib/malloc/malloc.c)
2129
2130         stdlib/malloc/malloc.c:
2131
2132         __malloc_init           <fix required>                          <---
2133         malloc                  <fix required>                          <---
2134         free                    <fix required>                          <---
2135         _realloc_no_move        <fix required>                          <---
2136         
2137         --------------------------------------------------------------------
2138
2139         Global variable:
2140
2141         __total_h (stdlib/malloc/malloc.c)
2142
2143         stdlib/malloc/malloc.c:
2144
2145         __hunk_alloc            <fix required>                          <---
2146         __malloc_init           <fix required>                          <---
2147         
2148         --------------------------------------------------------------------
2149
2150         Global variable:
2151
2152         errno (sysdeps/linux/common/errno.c)
2153
2154         sysdeps/linux/common/errno.c:
2155
2156         __errno_location        <fix required>                          <---
2157
2158         NOTE: Obviously, errno gets used all over the place.  I won't list
2159         them all here.
2160
2161         --------------------------------------------------------------------
2162
2163         Global variable:
2164
2165         ___brk_addr (sysdeps/linux/i386/__init_brk.c)
2166
2167         sysdeps/linux/i386/__init_brk.c:
2168
2169         __init_brk              <fix required>                          <---
2170
2171         sysdeps/linux/i386/brk.c:
2172
2173         brk                     <fix required>                          <---
2174
2175         sysdeps/linux/i386/sbrk.c:
2176
2177         sbrk                    <fix required>                          <---
2178
2179         --------------------------------------------------------------------
2180
2181         Global variable:
2182
2183         optarg (unistd/getopt_vars.c)
2184
2185         extra/locale/gen_ctype_from_glibc.c:
2186
2187         main                    <fix required?>                         (1)
2188
2189         ld.so-1/util/ldconfig.c:
2190
2191         main                    <fix required?>                         (1)
2192
2193         unistd/getopt.c:
2194
2195         getopt                  <fix required>                          <---
2196
2197         unistd/gnu_getopt.c:
2198
2199         _getopt_internal        <fix required>                          <---
2200         main                    <fix required?>                         (1)
2201
2202         1: Probably not required unless this program is run on multiple
2203         threads.
2204
2205         --------------------------------------------------------------------
2206
2207         Global variable:
2208
2209         opterr (unistd/getopt_vars.c)
2210
2211         ld.so-1/util/ldconfig.c:
2212
2213         main                    <fix required?>                         (1)
2214
2215         unistd/getopt.c:
2216
2217         Err                     <fix required>                          <---
2218         getopt                  <fix required>                          <---
2219
2220         unistd/gnu_getopt.c:
2221
2222         _getopt_internal        <fix required>                          <---
2223
2224         1: Probably not required unless this program is run on multiple
2225         threads.
2226
2227         --------------------------------------------------------------------
2228
2229         Global variable:
2230
2231         optind (unistd/getopt_vars.c)
2232
2233         extra/locale/gen_ctype_from_glibc.c:
2234
2235         main                    <fix required?>                         (1)
2236         
2237         ld.so-1/util/ldconfig.c:
2238
2239         main                    <fix required?>                         (1)
2240
2241         ld.so-1/util/ldd.c:
2242
2243         main                    <fix required?>                         (1)
2244         
2245         unistd/getopt.c:
2246
2247         Err                     <fix required>                          <---
2248         getopt                  <fix required>                          <---
2249
2250         unistd/gnu_getopt.c:
2251
2252         exchange                <fix required>                          <---
2253         _getopt_initialize      <fix required>                          <---
2254         _getopt_internal        <fix required>                          <---
2255         main                    <fix required?>                         (1)
2256         main (2nd one)          <fix required?>                         (1)
2257
2258         1: Probably not required unless this program is run on multiple
2259         threads.
2260
2261         --------------------------------------------------------------------
2262
2263         Global variable:
2264
2265         optopt (unistd/getopt_vars.c)
2266
2267         unistd/getopt.c:
2268
2269         Err                     <fix required>                          <---
2270         getopt                  <fix required>                          <---
2271
2272         unistd/gnu_getopt.c:
2273
2274         _getopt_internal        <fix required>                          <---
2275