1 | This patch (against rtems-ss20020301) adds support |
---|
2 | for libc environment locking by implementing |
---|
3 | |
---|
4 | __ENV_LOCK() / __ENV_UNLOCK(). |
---|
5 | |
---|
6 | Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002 |
---|
7 | |
---|
8 | Index: c/src/lib/libc/Makefile.am |
---|
9 | =================================================================== |
---|
10 | RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/Makefile.am,v |
---|
11 | retrieving revision 1.1.1.2 |
---|
12 | retrieving revision 1.2 |
---|
13 | diff -c -r1.1.1.2 -r1.2 |
---|
14 | *** c/src/lib/libc/Makefile.am 2002/03/07 01:53:46 1.1.1.2 |
---|
15 | --- c/src/lib/libc/Makefile.am 2002/03/28 20:59:16 1.2 |
---|
16 | *************** |
---|
17 | *** 32,37 **** |
---|
18 | --- 32,39 ---- |
---|
19 | |
---|
20 | MALLOC_C_FILES = malloc.c mallocfreespace.c __brk.c __sbrk.c |
---|
21 | |
---|
22 | + ENVIRON_C_FILES = envlock.c |
---|
23 | + |
---|
24 | PASSWORD_GROUP_C_FILES = getpwent.c getgrent.c |
---|
25 | |
---|
26 | TERMINAL_IDENTIFICATION_C_FILES = ctermid.c isatty.c ttyname.c ttyname_r.c |
---|
27 | *************** |
---|
28 | *** 42,48 **** |
---|
29 | UNIX_LIBC_C_FILES = unixlibc.c hosterr.c |
---|
30 | |
---|
31 | COMMON_C_FILES = gxx_wrappers.c printk.c $(BASE_FS_C_FILES) \ |
---|
32 | ! $(MALLOC_C_FILES) $(TERMIOS_C_FILES) $(ERROR_C_FILES) \ |
---|
33 | $(ASSOCIATION_C_FILES) |
---|
34 | |
---|
35 | UNIX_C_FILES = $(UNIX_LIBC_C_FILES) |
---|
36 | --- 44,50 ---- |
---|
37 | UNIX_LIBC_C_FILES = unixlibc.c hosterr.c |
---|
38 | |
---|
39 | COMMON_C_FILES = gxx_wrappers.c printk.c $(BASE_FS_C_FILES) \ |
---|
40 | ! $(MALLOC_C_FILES) $(ENVIRON_C_FILES) $(TERMIOS_C_FILES) $(ERROR_C_FILES) \ |
---|
41 | $(ASSOCIATION_C_FILES) |
---|
42 | |
---|
43 | UNIX_C_FILES = $(UNIX_LIBC_C_FILES) |
---|
44 | Index: c/src/lib/libc/envlock.c |
---|
45 | =================================================================== |
---|
46 | RCS file: envlock.c |
---|
47 | diff -N envlock.c |
---|
48 | *** /dev/null Thu Aug 24 02:00:32 2000 |
---|
49 | --- /tmp/cvsdJUa8N Sun May 5 11:22:32 2002 |
---|
50 | *************** |
---|
51 | *** 0 **** |
---|
52 | --- 1,79 ---- |
---|
53 | + /* |
---|
54 | + * $Id: envlock.c,v 1.2 2002/04/16 01:32:48 till Exp $ |
---|
55 | + * |
---|
56 | + * Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002 |
---|
57 | + */ |
---|
58 | + |
---|
59 | + /* provide locking for the global environment 'environ' */ |
---|
60 | + |
---|
61 | + #if HAVE_CONFIG_H |
---|
62 | + #include "config.h" |
---|
63 | + #endif |
---|
64 | + |
---|
65 | + #include <rtems.h> |
---|
66 | + #include <sys/reent.h> |
---|
67 | + |
---|
68 | + #include <assert.h> |
---|
69 | + |
---|
70 | + /* |
---|
71 | + * NOTES: |
---|
72 | + * - although it looks like a classical multiple-readers / single writer (MRSW) |
---|
73 | + * locking problem, we still use a single lock for the following reasons: |
---|
74 | + * 1) newlib has no provision / hook for calling different locking routines |
---|
75 | + * from setenv/putenv and getenv, respectively. |
---|
76 | + * 2) MRSW involves calling several semaphore-primitives, even in the most likely |
---|
77 | + * case of a first-reader's access. This probably takes more CPU |
---|
78 | + * time than just waiting until another reader is done; environment |
---|
79 | + * access is fast. |
---|
80 | + * - the lock implementation must allow nesting (same thread may call |
---|
81 | + * lock-lock-unlock-unlock). |
---|
82 | + * - NEWLIB-1.8.2 has an ugly BUG: if environ is NULL, _findenv_r() bails |
---|
83 | + * out leaving the lock held :-( |
---|
84 | + * |
---|
85 | + */ |
---|
86 | + |
---|
87 | + static rtems_id envLock=0; |
---|
88 | + |
---|
89 | + static void |
---|
90 | + __rtems_envlock_init(void) |
---|
91 | + { |
---|
92 | + extern char **environ; |
---|
93 | + rtems_status_code rc; |
---|
94 | + |
---|
95 | + if (envLock) /* already initialized */ |
---|
96 | + return; |
---|
97 | + |
---|
98 | + assert(environ && "MUST have non-NULL 'environ' due to newlib bug"); |
---|
99 | + |
---|
100 | + rc = rtems_semaphore_create( |
---|
101 | + rtems_build_name('E','N','V','S'), |
---|
102 | + 1, |
---|
103 | + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, |
---|
104 | + 0, |
---|
105 | + &envLock); |
---|
106 | + if (RTEMS_SUCCESSFUL!=rc) |
---|
107 | + rtems_fatal_error_occurred(rc); |
---|
108 | + } |
---|
109 | + |
---|
110 | + void |
---|
111 | + __env_lock(struct _reent *r) |
---|
112 | + { |
---|
113 | + /* Do lazy init */ |
---|
114 | + if (!envLock) |
---|
115 | + __rtems_envlock_init(); |
---|
116 | + /* Must not use a semaphore before multitasking is up |
---|
117 | + * - it will corrupt memory :-( |
---|
118 | + */ |
---|
119 | + if (_Thread_Executing) |
---|
120 | + rtems_semaphore_obtain(envLock, RTEMS_WAIT, RTEMS_NO_TIMEOUT); |
---|
121 | + } |
---|
122 | + |
---|
123 | + void |
---|
124 | + __env_unlock(struct _reent *r) |
---|
125 | + { |
---|
126 | + /* Must not use a semaphore before multitasking is up |
---|
127 | + * - it will corrupt memory :-( |
---|
128 | + */ |
---|
129 | + if (_Thread_Executing) |
---|
130 | + rtems_semaphore_release(envLock); |
---|
131 | + } |
---|