Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

sc_cor_qt.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2004 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 Version 2.3 (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.systemc.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_cor_qt.cpp -- Coroutine implementation with QuickThreads.
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
00033 
00034  *****************************************************************************/
00035 
00036 
00037 
00038 #if !defined(WIN32) && !defined(SC_USE_PTHREADS)
00039 
00040 #include <unistd.h>
00041 #include <sys/mman.h>
00042 
00043 #include "systemc/kernel/sc_cor_qt.h"
00044 #include "systemc/kernel/sc_simcontext.h"
00045 
00046 
00047 // ----------------------------------------------------------------------------
00048 //  File static variables.
00049 // ----------------------------------------------------------------------------
00050 
00051 // main coroutine
00052 
00053 static sc_cor_qt main_cor;
00054 
00055 // current coroutine
00056 
00057 static sc_cor_qt* curr_cor = 0;
00058 
00059 
00060 // ----------------------------------------------------------------------------
00061 //  CLASS : sc_cor_qt
00062 //
00063 //  Coroutine class implemented with QuickThreads.
00064 // ----------------------------------------------------------------------------
00065 
00066 // switch stack protection on/off
00067 
00068 void
00069 sc_cor_qt::stack_protect( bool enable )
00070 {
00071     // Code needs to be tested on HP-UX and disabled if it doesn't work there
00072     // Code still needs to be ported to WIN32
00073 
00074     static size_t pagesize;
00075     
00076     if( pagesize == 0 ) {
00077 #       if defined(__ppc__)
00078       pagesize = getpagesize();
00079 #       else
00080       pagesize = sysconf( _SC_PAGESIZE );
00081 #       endif 
00082     }
00083 
00084     assert( pagesize != 0 );
00085     assert( m_stack_size > ( 2 * pagesize ) );
00086 
00087 #ifdef QUICKTHREADS_GROW_DOWN
00088     // Stacks grow from high address down to low address
00089     caddr_t redzone = caddr_t( ( ( size_t( m_stack ) + pagesize - 1 ) /
00090          pagesize ) * pagesize );
00091 #else
00092     // Stacks grow from low address up to high address
00093     caddr_t redzone = caddr_t( ( ( size_t( m_stack ) +
00094            m_stack_size - pagesize ) /
00095          pagesize ) * pagesize );
00096 #endif
00097 
00098     int ret;
00099 
00100     if( enable ) {
00101   ret = mprotect( redzone, pagesize - 1, PROT_NONE );
00102     } else {
00103   ret = mprotect( redzone, pagesize - 1, PROT_READ | PROT_WRITE );
00104     }
00105 
00106     assert( ret == 0 );
00107 }
00108 
00109 
00110 // ----------------------------------------------------------------------------
00111 //  CLASS : sc_cor_pkg_qt
00112 //
00113 //  Coroutine package class implemented with QuickThreads.
00114 // ----------------------------------------------------------------------------
00115 
00116 int sc_cor_pkg_qt::instance_count = 0;
00117 
00118 
00119 // support function
00120 
00121 inline
00122 void*
00123 stack_align( void* sp, int alignment, size_t* stack_size )
00124 {
00125     int round_up_mask = alignment - 1;
00126     *stack_size = (*stack_size + round_up_mask) & ~round_up_mask;
00127     return ( (void*)(((qt_word_t) sp + round_up_mask) & ~round_up_mask) );
00128 }
00129 
00130 
00131 // constructor
00132 
00133 sc_cor_pkg_qt::sc_cor_pkg_qt( sc_simcontext* simc )
00134 : sc_cor_pkg( simc )
00135 {
00136     if( ++ instance_count == 1 ) {
00137   // initialize the current coroutine
00138   assert( curr_cor == 0 );
00139   curr_cor = &main_cor;
00140     }
00141 }
00142 
00143 
00144 // destructor
00145 
00146 sc_cor_pkg_qt::~sc_cor_pkg_qt()
00147 {
00148     if( -- instance_count == 0 ) {
00149   // cleanup the current coroutine
00150   curr_cor = 0;
00151     }
00152 }
00153 
00154 
00155 // create a new coroutine
00156 
00157 extern "C"
00158 void
00159 sc_cor_qt_wrapper( void* arg, void* cor, qt_userf_t* fn )
00160 {
00161     curr_cor = RCAST<sc_cor_qt*>( cor );
00162     // invoke the user function
00163     (*(sc_cor_fn*) fn)( arg );
00164     // not reached
00165 }
00166 
00167 sc_cor*
00168 sc_cor_pkg_qt::create( size_t stack_size, sc_cor_fn* fn, void* arg )
00169 {
00170     sc_cor_qt* cor = new sc_cor_qt();
00171     cor->m_pkg = this;
00172     cor->m_stack_size = stack_size;
00173     cor->m_stack = new char[cor->m_stack_size];
00174     void* sto = stack_align( cor->m_stack, QUICKTHREADS_STKALIGN, &cor->m_stack_size );
00175     cor->m_sp = QUICKTHREADS_SP( sto, cor->m_stack_size - QUICKTHREADS_STKALIGN );
00176     cor->m_sp = QUICKTHREADS_ARGS( cor->m_sp, arg, cor, (qt_userf_t*) fn,
00177        sc_cor_qt_wrapper );
00178     return cor;
00179 }
00180 
00181 
00182 // yield to the next coroutine
00183 
00184 extern "C"
00185 void*
00186 sc_cor_qt_yieldhelp( qt_t* sp, void* old_cor, void* )
00187 {
00188     RCAST<sc_cor_qt*>( old_cor )->m_sp = sp;
00189     return 0;
00190 }
00191 
00192 void
00193 sc_cor_pkg_qt::yield( sc_cor* next_cor )
00194 {
00195     sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor );
00196     sc_cor_qt* old_cor = curr_cor;
00197     curr_cor = new_cor;
00198     QUICKTHREADS_BLOCK( sc_cor_qt_yieldhelp, old_cor, 0, new_cor->m_sp );
00199 }
00200 
00201 
00202 // abort the current coroutine (and resume the next coroutine)
00203 
00204 extern "C"
00205 void*
00206 sc_cor_qt_aborthelp( qt_t*, void*, void* )
00207 {
00208     return 0;
00209 }
00210 
00211 void
00212 sc_cor_pkg_qt::abort( sc_cor* next_cor )
00213 {
00214     sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor );
00215     sc_cor_qt* old_cor = curr_cor;
00216     curr_cor = new_cor;
00217     QUICKTHREADS_ABORT( sc_cor_qt_aborthelp, old_cor, 0, new_cor->m_sp );
00218 }
00219 
00220 
00221 // get the main coroutine
00222 
00223 sc_cor*
00224 sc_cor_pkg_qt::get_main()
00225 {
00226     return &main_cor;
00227 }
00228 
00229 #endif
00230 
00231 
00232 // Taf!

Generated on Fri Jan 14 08:29:00 2005 for SystemC2.1beta11(excludingMSLib)(IncludingSCV)\nProvidedby:www.openverificationfoundation.org by doxygen1.2.18