summaryrefslogtreecommitdiff
path: root/lib/libc_r/NOTES
blob: 25669e05d0b016ae29965aec8c935894e1944731 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

Notes on the OpenBSD threaded C library  (-lc_r)
================================================

Sources

  The main bulk of this library came from:
   . FreeBSD's libc_r (John Birrell)
     - The scheduler and locking code in the uthread directory.
     - Some of the manual pages in the man directory.
     - <pthreads.h>
   . MIT pthreads (Chris Provenzano)
     - The test code in the TEST directory

  I'm mainly tracking changes in FreeBSD's libc_r and integrating them
  as I can. The major changes to Birrell's code involved making the
  context switching a bit more architecture-independent.

Standards

  This implementation has also been mindful of:
   . Posix Threads[1]
   . Single Unix Specification[2]

Header files

  Only the absolutely required re-entrant functions have been added to
  the C library interface headers in /usr/src/include. 

  The new functions are:
	readdir_r()		<dirent.h>
	sigwait()		<signal.h>
	flockfile()		<stdio.h>
	ftrylockfile()		<stdio.h>
	funclockfile()		<stdio.h>
	getc_unlocked()		<stdio.h>
	getchar_unlocked()	<stdio.h>
	putc_unlocked()		<stdio.h>
	putchar_unlocked()	<stdio.h>
	rand_r()		<stdlib.h>
	strtok_r()		<string.h>
	asctime_r()		<time.h>
	ctime_r()		<time.h>
	gmtime_r()		<time.h>
	localtime_r()		<time.h>

  The widely used, but non-standard, gethostbyname_r() needs thought.

  These functions are available even when not using the thread package;
  i.e., they are also in the non-threaded libc.a. 

  See below why <sys/errno.h> has not been changed.

Changes to libc sources

  The approach taken to making the libc functions re-entrant was to
  develop some macros that handle:
	. file locking
	. monitors (thread-shared data structure locking)
	. per-thread private data structure allocation

  Macros were used to avoid copious amounts of #ifdef statements[3].

  In the non-threaded libc, file locking and the monitors are no-ops;
  the per-thread private data structures were previously declared static
  and the macros maintain this.

  In the threaded libc_r, file locking is as per the FreeBSD file
  descriptor locking, and the monitors are pthread_mutex operations.
  Per-thread private data structures use the pthread_specific functions
  to dynamically allocate memory on their first use, initialising
  them from the static (and hidden) per-compilation-unit data structures.

Errno

  Unlike the FreeBSD and MIT pthreads package, errno is not a macro;
  instead it is part of the per-thread context and saved and restored like
  a register. This has several advantages over the errno-as-a-macro method:

    - The syscall/cerror code does not have to be re-written
    - Libraries compiled without thread support will still work
    - Easier to port packages that use errno, but don't include <errno.h>

  The overhead of saving and restoring an integer was considered too tiny
  to worry about in comparison to the huge penalty hit of handling a
  signal and restoring the rest of a thread's context.

  It has been pointed out that this technique will not work in a
  mutiprocessor environment, and this is quite true. However the following
  reasons are quite persuasive:

    - OpenBSD does not do MP (yet)
    - This (FreeBSD uthread) implementation will not work in an MP 
      environment anyway because _thread_run is not a cpu-local variable.
    - There is a lot of coupling between binary ports and old libc and
      other libraries that is quite a big headache to resolve in a
      friendly manner.

Compiler Support

  The in-tree gcc had its config/openbsd.h modified to support a
  `-pthread' switch. Using this switch defines _POSIX_THREADS for cpp, and
  replaces the normal -lc linker option with -lc_r. 

  The objective-C component was also made aware of posix threads, via
  the configure switch --enable-threads=posix.

Changes to FreeBSD uthreads

  The following significant changes have been made to John Birrell's
  uthreads implementation:

    - the SIGINFO handler generates much more friendly output

Caveats

  Not everything above is working right now: read the TODO file.

Standard disclaimer

   This software is made available by the author to the public for free
   and "as is".  All users of this free software are solely and entirely
   responsible for their own choice and use of this software for their
   own purposes.  By using this software, each user agrees that the
   author shall not be liable for damages of any kind in relation to
   its use or performance.

   Some parts of this software bear a copyright.

References

   [1] P1003.1c/D10 IEEE Draft Standard for Information Technology--
       Portable Operating System Interface (POSIX) -- Part 1: System
       Application Program Interface (API) -- Ammendment 2: Threads
       Extension [C Language]. IEEE Standards, September 1994.
   [2] T912, The Single UNIX(R) Specification, Version 2. The Open 
       Group, February 1997. http://www.opengroup.org/pubs/catalog/t912.htm
   [3] #ifdef Considered Harmful, or Portability Experience with C News.
       H. Spencer and G. Collyer, Proc. of the Summer 1992 USENIX Conference,
       San Antionio, Texas, 1992. pp. 185-198

David Leonard <leonard@csee.uq.edu.au>
$OpenBSD: NOTES,v 1.2 1999/01/10 22:50:07 d Exp $