00001 /***************************************************************************** 00002 00003 The following code is derived, directly or indirectly, from the SystemC 00004 source code Copyright (c) 1996-2014 by all Contributors. 00005 All Rights reserved. 00006 00007 The contents of this file are subject to the restrictions and limitations 00008 set forth in the SystemC Open Source License (the "License"); 00009 You may not use this file except in compliance with such restrictions and 00010 limitations. You may obtain instructions on how to receive a copy of the 00011 License at http://www.accellera.org/. Software distributed by Contributors 00012 under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 00013 ANY KIND, either express or implied. See the License for the specific 00014 language governing rights and limitations under the License. 00015 00016 *****************************************************************************/ 00017 00018 /***************************************************************************** 00019 00020 sc_spawn.h -- Process spawning support. 00021 00022 Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003 00023 Stuart Swan, Cadence, 00024 Bishnupriya Bhattacharya, Cadence Design Systems, 00025 25 August, 2003 00026 00027 CHANGE LOG AT THE END OF THE FILE 00028 *****************************************************************************/ 00029 00030 00031 #if !defined(sc_spawn_h_INCLUDED) 00032 #define sc_spawn_h_INCLUDED 00033 00034 #include "sysc/kernel/sc_process_handle.h" 00035 #include "sysc/kernel/sc_spawn_options.h" 00036 00037 namespace sc_core { 00038 00039 class sc_event; 00040 class sc_port_base; 00041 class sc_interface; 00042 class sc_event_finder; 00043 class sc_process_b; 00044 00045 /**************************************************************************/ 00074 template<typename T> 00075 class sc_spawn_object : public sc_process_host { 00076 public: 00077 sc_spawn_object( T object) : m_object(object) 00078 { 00079 } 00080 00081 virtual void semantics() 00082 { 00083 m_object(); 00084 } 00085 00086 protected: 00087 T m_object; 00088 }; 00089 00090 00091 /**************************************************************************/ 00112 template <typename T> 00113 inline sc_process_handle sc_spawn( 00114 T object, 00115 const char* name_p = 0, 00116 const sc_spawn_options* opt_p = 0) 00117 { 00118 sc_simcontext* context_p; 00119 sc_spawn_object<T>* spawn_p; 00120 00121 assert( 0 ); // 08/20/2015 GL: to support sc_spawn in the future 00122 00123 context_p = sc_get_curr_simcontext(); 00124 spawn_p = new sc_spawn_object<T>(object); 00125 if ( !opt_p || !opt_p->is_method() ) 00126 { 00127 // 05/25/2015 GL: sc_kernel_lock constructor acquires the kernel lock 00128 sc_kernel_lock lock; 00129 00130 // 05/27/2015 GL: we may or may not have acquired the kernel lock 00131 // (static vs. dynamic spawn) 00132 00133 sc_process_handle thread_handle = context_p->create_thread_process( 00134 name_p, true, 00135 SC_MAKE_FUNC_PTR(sc_spawn_object<T>,semantics), 00136 spawn_p, opt_p, 00137 -2, // 08/20/2015 GL: fake segment ID 00138 -2 // 09/02/2015 GL: fake instance ID 00139 ); 00140 return thread_handle; 00141 // 05/25/2015 GL: sc_kernel_lock destructor releases the kernel lock 00142 } 00143 else 00144 { 00145 // 05/25/2015 GL: sc_kernel_lock constructor acquires the kernel lock 00146 sc_kernel_lock lock; 00147 00148 // 05/27/2015 GL: we may or may not have acquired the kernel lock 00149 // (static vs. dynamic spawn) 00150 00151 sc_process_handle method_handle = context_p->create_method_process( 00152 name_p, true, 00153 SC_MAKE_FUNC_PTR(sc_spawn_object<T>,semantics), 00154 spawn_p, opt_p, 00155 -2, // 08/20/2015 GL: fake segment ID 00156 -2 // 09/02/2015 GL: fake instance ID 00157 ); 00158 return method_handle; 00159 // 05/25/2015 GL: sc_kernel_lock destructor releases the kernel lock 00160 } 00161 } 00162 00163 //============================================================================= 00164 // CLASS sc_spawn_object_v<T> for all compilers except HP aCC 00165 // or 00166 // CLASS sc_spawn_object_v<T, R> for HP aCC which tries to match this 00167 // one template argument class when the sc_spawn() declared above is 00168 // invoked with 3 arguments or 2 arguments, and generates compiler errors. 00169 // 00170 // This templated helper class allows an object to provide the execution 00171 // semantics for a process via its () operator. An instance of the supplied 00172 // object will be kept to provide the semantics when the process is scheduled 00173 // for execution. The () operator returns a value, which will be stored at the 00174 // location specified by the supplied pointer. An example of an object that 00175 // might be used for this helper function would be valued SC_BOOST bound 00176 // function or method. 00177 // 00178 // sc_spawn_object_v( typename F::result_type* r_p, T f, const char* name_p, 00179 // const sc_spawn_options* opt_p ) 00180 // r_p -> where to place the result of the function invocation. 00181 // f = information to be executed. 00182 // name_p = optional name for object instance, or zero. 00183 // opt_p -> optional spawn options for process, or zero for the default 00184 // This is the object instance constructor for this class. It makes a 00185 // copy of the supplied object. The tp_call constructor is called 00186 // with an indication that this object instance should be reclaimed when 00187 // execution completes. 00188 // result_p -> where to place the value of the () operator. 00189 // object = object whose () operator will be called to provide 00190 // the process semantics. 00191 // 00192 // virtual void semantics() 00193 // This virtual method provides the execution semantics for its process. 00194 // It performs a () operation on m_object, placing the result at m_result_p. 00195 //============================================================================= 00196 00197 /**************************************************************************/ 00218 #if !defined (__HP_aCC) 00219 00220 template<typename T> 00221 class sc_spawn_object_v : public sc_process_host { 00222 public: 00223 sc_spawn_object_v( typename T::result_type* r_p, T object ) : 00224 m_object(object), m_result_p(r_p) 00225 { 00226 } 00227 00228 virtual void semantics() 00229 { 00230 *m_result_p = m_object(); 00231 } 00232 00233 protected: 00234 T m_object; 00235 typename T::result_type* m_result_p; 00236 }; 00237 00242 // 08/20/2015 GL. 00243 template <typename T> 00244 inline sc_process_handle sc_spawn( 00245 typename T::result_type* r_p, 00246 T object, 00247 const char* name_p = 0, 00248 const sc_spawn_options* opt_p = 0) 00249 { 00250 sc_simcontext* context_p; 00251 sc_spawn_object_v<T>* spawn_p; 00252 00253 assert( 0 ); // 08/20/2015 GL: to support sc_spawn in the future 00254 00255 context_p = sc_get_curr_simcontext(); 00256 00257 spawn_p = new sc_spawn_object_v<T>(r_p, object); 00258 if ( !opt_p || !opt_p->is_method() ) 00259 { 00260 // 05/25/2015 GL: sc_kernel_lock constructor acquires the kernel lock 00261 sc_kernel_lock lock; 00262 00263 // 05/27/2015 GL: we may or may not have acquired the kernel lock 00264 // (static vs. dynamic spawn) 00265 00266 sc_process_handle thread_handle = context_p->create_thread_process( 00267 name_p, true, 00268 SC_MAKE_FUNC_PTR(sc_spawn_object_v<T>,semantics), 00269 spawn_p, opt_p, 00270 -2, // 08/20/2015 GL: fake segment ID 00271 -2 // 09/02/2015 GL: fake instance ID 00272 ); 00273 return thread_handle; 00274 // 05/25/2015 GL: sc_kernel_lock destructor releases the kernel lock 00275 } 00276 else 00277 { 00278 // 05/25/2015 GL: sc_kernel_lock constructor acquires the kernel lock 00279 sc_kernel_lock lock; 00280 00281 // 05/27/2015 GL: we may or may not have acquired the kernel lock 00282 // (static vs. dynamic spawn) 00283 00284 sc_process_handle method_handle = context_p->create_method_process( 00285 name_p, true, 00286 SC_MAKE_FUNC_PTR(sc_spawn_object_v<T>,semantics), 00287 spawn_p, opt_p, 00288 -2, // 08/20/2015 GL: fake segment ID 00289 -2 // 09/02/2015 GL: fake instance ID 00290 ); 00291 return method_handle; 00292 // 05/25/2015 GL: sc_kernel_lock destructor releases the kernel lock 00293 } 00294 } 00295 00296 #else 00297 // for HP aCC 00298 template<typename T, typename R> 00299 class sc_spawn_object_v : public sc_process_host { 00300 public: 00301 sc_spawn_object_v( R* r_p, T object) : 00302 m_object(object), m_result_p(r_p) 00303 { 00304 } 00305 00306 virtual void semantics() 00307 { 00308 *m_result_p = m_object(); 00309 } 00310 00311 protected: 00312 T m_object; 00313 R* m_result_p; 00314 }; 00315 00320 // 08/20/2015 GL. 00321 template <typename T, typename R> 00322 inline sc_process_handle sc_spawn( 00323 R* r_p, 00324 T object, 00325 const char* name_p = 0, 00326 const sc_spawn_options* opt_p = 0) 00327 { 00328 sc_simcontext* context_p; 00329 sc_spawn_object_v<T,R>* spawn_p; 00330 00331 assert( 0 ); // 08/20/2015 GL: to support sc_spawn in the future 00332 00333 context_p = sc_get_curr_simcontext(); 00334 00335 spawn_p = new sc_spawn_object_v<T,R>(r_p, object); 00336 if ( !opt_p || !opt_p->is_method() ) 00337 { 00338 // 05/25/2015 GL: sc_kernel_lock constructor acquires the kernel lock 00339 sc_kernel_lock lock; 00340 00341 // 05/27/2015 GL: we may or may not have acquired the kernel lock 00342 // (static vs. dynamic spawn) 00343 00344 sc_process_handle thread_handle = context_p->create_thread_process( 00345 name_p, true, 00346 static_cast<sc_core::SC_ENTRY_FUNC>( 00347 &sc_spawn_object_v<T,R>::semantics), 00348 spawn_p, opt_p, 00349 -2, // 08/20/2015 GL: fake segment ID 00350 -2 // 09/02/2015 GL: fake instance ID 00351 ); 00352 return thread_handle; 00353 // 05/25/2015 GL: sc_kernel_lock destructor releases the kernel lock 00354 } 00355 else 00356 { 00357 // 05/25/2015 GL: sc_kernel_lock constructor acquires the kernel lock 00358 sc_kernel_lock lock; 00359 00360 // 05/27/2015 GL: we may or may not have acquired the kernel lock 00361 // (static vs. dynamic spawn) 00362 00363 sc_process_handle method_handle = context_p->create_method_process( 00364 name_p, true, 00365 static_cast<sc_core::SC_ENTRY_FUNC>( 00366 &sc_spawn_object_v<T,R>::semantics), 00367 spawn_p, opt_p, 00368 -2, // 08/20/2015 GL: fake segment ID 00369 -2 // 09/02/2015 GL: fake instance ID 00370 ); 00371 return method_handle; 00372 // 05/25/2015 GL: sc_kernel_lock destructor releases the kernel lock 00373 } 00374 } 00375 00376 #endif // HP 00377 00378 } // namespace sc_core 00379 00380 // $Log: sc_spawn.h,v $ 00381 // Revision 1.7 2011/08/26 20:46:11 acg 00382 // Andy Goodrich: moved the modification log to the end of the file to 00383 // eliminate source line number skew when check-ins are done. 00384 // 00385 // Revision 1.6 2011/02/18 20:27:14 acg 00386 // Andy Goodrich: Updated Copyrights. 00387 // 00388 // Revision 1.5 2011/02/13 21:47:38 acg 00389 // Andy Goodrich: update copyright notice. 00390 // 00391 // Revision 1.4 2011/02/01 21:14:02 acg 00392 // Andy Goodrich: formatting. 00393 // 00394 // Revision 1.3 2009/07/28 01:10:53 acg 00395 // Andy Goodrich: updates for 2.3 release candidate. 00396 // 00397 // Revision 1.2 2008/05/22 17:06:26 acg 00398 // Andy Goodrich: updated copyright notice to include 2008. 00399 // 00400 // Revision 1.1.1.1 2006/12/15 20:20:05 acg 00401 // SystemC 2.3 00402 // 00403 // Revision 1.6 2006/05/26 20:33:16 acg 00404 // Andy Goodrich: changes required by additional platform compilers (i.e., 00405 // Microsoft VC++, Sun Forte, HP aCC). 00406 // 00407 // Revision 1.5 2006/05/08 18:01:44 acg 00408 // Andy Goodrich: changed the HP-specific implementations of sc_spawn() to 00409 // use a static_cast to create their entry functions rather than the 00410 // SC_MAKE_FUNC_PTR macro. The HP preprocessor does not parse template 00411 // arguments that contain a comma properly. 00412 // 00413 // Revision 1.4 2006/04/11 23:13:21 acg 00414 // Andy Goodrich: Changes for reduced reset support that only includes 00415 // sc_cthread, but has preliminary hooks for expanding to method and thread 00416 // processes also. 00417 // 00418 // Revision 1.3 2006/01/13 18:44:30 acg 00419 // Added $Log to record CVS changes into the source. 00420 00421 #endif // !defined(sc_spawn_h_INCLUDED)