|
0
|
1 //=========================================================================== |
|
|
2 // |
|
|
3 // compatmode.cxx |
|
|
4 // |
|
|
5 // Compatibility mode setting for Math library |
|
|
6 // |
|
|
7 //=========================================================================== |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
2
|
25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
|
0
|
26 // ------------------------------------------- |
|
|
27 // |
|
|
28 //####COPYRIGHTEND#### |
|
|
29 //=========================================================================== |
|
|
30 //#####DESCRIPTIONBEGIN#### |
|
|
31 // |
|
2
|
32 // Author(s): jlarmour |
|
|
33 // Contributors: jlarmour |
|
0
|
34 // Date: 1998-02-13 |
|
|
35 // Purpose: |
|
|
36 // Description: Contains the accessor functions to get and set the standards |
|
|
37 // compatibility mode of the Math library |
|
|
38 // Usage: |
|
|
39 // |
|
|
40 //####DESCRIPTIONEND#### |
|
|
41 // |
|
|
42 //=========================================================================== |
|
|
43 |
|
|
44 // CONFIGURATION |
|
|
45 |
|
|
46 #include <pkgconf/libm.h> // Configuration header |
|
|
47 |
|
|
48 // Include the Math library? |
|
|
49 #ifdef CYGPKG_LIBM |
|
|
50 |
|
|
51 // INCLUDES |
|
|
52 |
|
|
53 #include <cyg/infra/cyg_type.h> // Common type definitions and support |
|
|
54 #include <cyg/infra/cyg_trac.h> // Tracing macros |
|
|
55 |
|
|
56 #include <math.h> // Main header for math library |
|
|
57 |
|
|
58 #ifdef CYGSEM_LIBM_THREAD_SAFE_COMPAT_MODE |
|
2
|
59 # include <pkgconf/kernel.h> // Kernel configuration |
|
0
|
60 # include <cyg/kernel/thread.hxx> // Kernel thread header |
|
|
61 # include <cyg/kernel/thread.inl> // and its associated inlines |
|
|
62 # include <cyg/kernel/mutex.hxx> // We need mutexes too |
|
|
63 #endif |
|
|
64 |
|
|
65 // GLOBAL VARIABLES |
|
|
66 |
|
|
67 #ifndef CYGSEM_LIBM_THREAD_SAFE_COMPAT_MODE |
|
|
68 |
|
|
69 # ifdef CYGSEM_LIBM_COMPAT_IEEE_ONLY |
|
|
70 Cyg_libm_compat_t cygvar_libm_compat_mode = CYGNUM_LIBM_COMPAT_IEEE; |
|
|
71 # else |
|
|
72 Cyg_libm_compat_t cygvar_libm_compat_mode = CYGNUM_LIBM_COMPAT_DEFAULT; |
|
|
73 # endif |
|
|
74 |
|
|
75 #else // ifndef CYGSEM_LIBM_THREAD_SAFE_COMPAT_MODE |
|
|
76 |
|
|
77 static Cyg_Mutex cyg_libm_mode_thread_data_index_mutex; |
|
|
78 static cyg_count32 cyg_libm_mode_thread_data_index = CYGNUM_KERNEL_THREADS_DATA_MAX; |
|
|
79 |
|
|
80 |
|
|
81 # if defined(CYGDBG_USE_TRACING) && \ |
|
|
82 defined(CYGNUM_LIBM_COMPATMODE_TRACE_LEVEL) |
|
|
83 static int libm_compatmode_trace = CYGNUM_LIBM_COMPATMODE_TRACE_LEVEL; |
|
|
84 # define TL1 (0 < libm_compatmode_trace ) |
|
|
85 # else |
|
|
86 # define TL1 (0) |
|
|
87 # endif |
|
|
88 |
|
|
89 // FUNCTIONS |
|
|
90 |
|
|
91 |
|
|
92 Cyg_libm_compat_t |
|
|
93 cyg_libm_get_compat_mode( void ) |
|
|
94 { |
|
|
95 Cyg_Thread *self = Cyg_Thread::self(); |
|
|
96 CYG_ADDRWORD current_val; |
|
|
97 |
|
|
98 CYG_REPORT_FUNCNAMETYPE( "Cyg_libm_get_compat_mode", "mode is %d" ); |
|
|
99 |
|
|
100 // First check if this is the first thread to get here, and if so, |
|
|
101 // initialise the thread data index |
|
|
102 |
|
|
103 if (cyg_libm_mode_thread_data_index == CYGNUM_KERNEL_THREADS_DATA_MAX) |
|
|
104 { |
|
|
105 CYG_TRACE0( TL1, "Index unset, locking mutex to allocate" ); |
|
|
106 |
|
|
107 // Lock mutex and then check again - less overhead for normal |
|
|
108 // execution path |
|
|
109 cyg_libm_mode_thread_data_index_mutex.lock(); |
|
|
110 |
|
|
111 if (cyg_libm_mode_thread_data_index == CYGNUM_KERNEL_THREADS_DATA_MAX) |
|
|
112 { |
|
|
113 CYG_TRACE0( TL1, "Allocating index" ); |
|
|
114 cyg_libm_mode_thread_data_index = self->new_data_index(); |
|
|
115 |
|
|
116 } // if |
|
|
117 |
|
|
118 cyg_libm_mode_thread_data_index_mutex.unlock(); |
|
|
119 |
|
|
120 self->set_data( cyg_libm_mode_thread_data_index, |
|
|
121 CYGNUM_LIBM_COMPAT_DEFAULT ); |
|
|
122 |
|
|
123 // But if we've gone through this, then we know what the mode is! |
|
|
124 CYG_REPORT_RETVAL( CYGNUM_LIBM_COMPAT_DEFAULT ); |
|
|
125 return CYGNUM_LIBM_COMPAT_DEFAULT; |
|
|
126 } // if |
|
|
127 |
|
|
128 CYG_TRACE0( TL1, "Index set, now fetching per-thread data" ); |
|
|
129 |
|
|
130 // If we're here, then the index is set up |
|
|
131 |
|
|
132 current_val = self->get_data( cyg_libm_mode_thread_data_index ); |
|
|
133 |
|
|
134 // If its at the "default" setting, then return the default |
|
|
135 if (current_val == CYGNUM_LIBM_COMPAT_UNINIT) |
|
|
136 { |
|
|
137 CYG_REPORT_RETVAL( CYGNUM_LIBM_COMPAT_DEFAULT ); |
|
|
138 return CYGNUM_LIBM_COMPAT_DEFAULT; |
|
|
139 } // if |
|
|
140 |
|
|
141 CYG_REPORT_RETVAL( current_val ); |
|
|
142 return (Cyg_libm_compat_t) current_val; |
|
|
143 } // cyg_libm_get_compat_mode() |
|
|
144 |
|
|
145 |
|
|
146 Cyg_libm_compat_t |
|
|
147 cyg_libm_set_compat_mode( Cyg_libm_compat_t new_mode ) |
|
|
148 { |
|
|
149 Cyg_Thread *self = Cyg_Thread::self(); |
|
|
150 CYG_ADDRWORD current_val; |
|
|
151 |
|
|
152 CYG_REPORT_FUNCNAMETYPE( "Cyg_libm_set_compat_mode", "old mode was %d" ); |
|
|
153 CYG_REPORT_FUNCARG1DV( new_mode ); |
|
|
154 |
|
|
155 // First check if this is the first thread to get here, and if so, |
|
|
156 // initialise the thread data index |
|
|
157 |
|
|
158 if (cyg_libm_mode_thread_data_index == CYGNUM_KERNEL_THREADS_DATA_MAX) |
|
|
159 { |
|
|
160 CYG_TRACE0( TL1, "Index unset, locking mutex to allocate" ); |
|
|
161 |
|
|
162 // Lock mutex and then check again - less overhead for normal |
|
|
163 // execution path |
|
|
164 cyg_libm_mode_thread_data_index_mutex.lock(); |
|
|
165 |
|
|
166 if (cyg_libm_mode_thread_data_index == CYGNUM_KERNEL_THREADS_DATA_MAX) |
|
|
167 { |
|
|
168 CYG_TRACE0( TL1, "Allocating index" ); |
|
|
169 cyg_libm_mode_thread_data_index = self->new_data_index(); |
|
|
170 |
|
|
171 } // if |
|
|
172 |
|
|
173 cyg_libm_mode_thread_data_index_mutex.unlock(); |
|
|
174 |
|
|
175 self->set_data( cyg_libm_mode_thread_data_index, |
|
|
176 new_mode ); |
|
|
177 |
|
|
178 // But if we've gone through this, then we know what the old mode was! |
|
|
179 |
|
|
180 CYG_REPORT_RETVAL( CYGNUM_LIBM_COMPAT_UNINIT ); |
|
|
181 return CYGNUM_LIBM_COMPAT_UNINIT; |
|
|
182 |
|
|
183 } // if |
|
|
184 |
|
|
185 // If we're here, then the index is set up |
|
|
186 |
|
|
187 CYG_TRACE0( TL1, "Index set, now fetching per-thread data" ); |
|
|
188 |
|
|
189 current_val = self->get_data( cyg_libm_mode_thread_data_index ); |
|
|
190 |
|
|
191 self->set_data( cyg_libm_mode_thread_data_index, |
|
|
192 new_mode ); |
|
|
193 |
|
|
194 CYG_REPORT_RETVAL( current_val ); |
|
|
195 return (Cyg_libm_compat_t) current_val; |
|
|
196 |
|
|
197 } // cyg_libm_set_compat_mode() |
|
|
198 |
|
|
199 #endif // ifdef CYGSEM_LIBM_THREAD_SAFE_COMPAT_MODE |
|
|
200 |
|
|
201 |
|
|
202 #endif // ifdef CYGPKG_LIBM |
|
|
203 |
|
|
204 // EOF compatmode.cxx |