00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00049
00050
00051
00052
00053 static sc_cor_qt main_cor;
00054
00055
00056
00057 static sc_cor_qt* curr_cor = 0;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 void
00069 sc_cor_qt::stack_protect( bool enable )
00070 {
00071
00072
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
00089 caddr_t redzone = caddr_t( ( ( size_t( m_stack ) + pagesize - 1 ) /
00090 pagesize ) * pagesize );
00091 #else
00092
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
00112
00113
00114
00115
00116 int sc_cor_pkg_qt::instance_count = 0;
00117
00118
00119
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
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
00138 assert( curr_cor == 0 );
00139 curr_cor = &main_cor;
00140 }
00141 }
00142
00143
00144
00145
00146 sc_cor_pkg_qt::~sc_cor_pkg_qt()
00147 {
00148 if( -- instance_count == 0 ) {
00149
00150 curr_cor = 0;
00151 }
00152 }
00153
00154
00155
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
00163 (*(sc_cor_fn*) fn)( arg );
00164
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
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
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
00222
00223 sc_cor*
00224 sc_cor_pkg_qt::get_main()
00225 {
00226 return &main_cor;
00227 }
00228
00229 #endif
00230
00231
00232