112027Sjungma@eit.uni-kl.de/***************************************************************************** 212027Sjungma@eit.uni-kl.de 312027Sjungma@eit.uni-kl.de Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412027Sjungma@eit.uni-kl.de more contributor license agreements. See the NOTICE file distributed 512027Sjungma@eit.uni-kl.de with this work for additional information regarding copyright ownership. 612027Sjungma@eit.uni-kl.de Accellera licenses this file to you under the Apache License, Version 2.0 712027Sjungma@eit.uni-kl.de (the "License"); you may not use this file except in compliance with the 812027Sjungma@eit.uni-kl.de License. You may obtain a copy of the License at 912027Sjungma@eit.uni-kl.de 1012027Sjungma@eit.uni-kl.de http://www.apache.org/licenses/LICENSE-2.0 1112027Sjungma@eit.uni-kl.de 1212027Sjungma@eit.uni-kl.de Unless required by applicable law or agreed to in writing, software 1312027Sjungma@eit.uni-kl.de distributed under the License is distributed on an "AS IS" BASIS, 1412027Sjungma@eit.uni-kl.de WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512027Sjungma@eit.uni-kl.de implied. See the License for the specific language governing 1612027Sjungma@eit.uni-kl.de permissions and limitations under the License. 1712027Sjungma@eit.uni-kl.de 1812027Sjungma@eit.uni-kl.de *****************************************************************************/ 1912027Sjungma@eit.uni-kl.de 2012027Sjungma@eit.uni-kl.de/***************************************************************************** 2112027Sjungma@eit.uni-kl.de 2212027Sjungma@eit.uni-kl.de sc_cor_qt.cpp -- Coroutine implementation with QuickThreads. 2312027Sjungma@eit.uni-kl.de 2412027Sjungma@eit.uni-kl.de Original Author: Martin Janssen, Synopsys, Inc., 2001-12-18 2512027Sjungma@eit.uni-kl.de 2612027Sjungma@eit.uni-kl.de CHANGE LOG APPEARS AT THE END OF THE FILE 2712027Sjungma@eit.uni-kl.de *****************************************************************************/ 2812027Sjungma@eit.uni-kl.de 2912027Sjungma@eit.uni-kl.de#if !defined(_WIN32) && !defined(WIN32) && !defined(SC_USE_PTHREADS) 3012027Sjungma@eit.uni-kl.de 3112027Sjungma@eit.uni-kl.de#include <unistd.h> 3212027Sjungma@eit.uni-kl.de#include <sys/mman.h> 3312027Sjungma@eit.uni-kl.de#include <sys/types.h> 3412027Sjungma@eit.uni-kl.de 3512027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_cor_qt.h" 3612027Sjungma@eit.uni-kl.de#include "sysc/kernel/sc_simcontext.h" 3712027Sjungma@eit.uni-kl.de 3812027Sjungma@eit.uni-kl.denamespace sc_core { 3912027Sjungma@eit.uni-kl.de 4012027Sjungma@eit.uni-kl.de// ---------------------------------------------------------------------------- 4112027Sjungma@eit.uni-kl.de// File static variables. 4212027Sjungma@eit.uni-kl.de// ---------------------------------------------------------------------------- 4312027Sjungma@eit.uni-kl.de 4412027Sjungma@eit.uni-kl.de// main coroutine 4512027Sjungma@eit.uni-kl.de 4612027Sjungma@eit.uni-kl.destatic sc_cor_qt main_cor; 4712027Sjungma@eit.uni-kl.de 4812027Sjungma@eit.uni-kl.de// current coroutine 4912027Sjungma@eit.uni-kl.de 5012027Sjungma@eit.uni-kl.destatic sc_cor_qt* curr_cor = 0; 5112027Sjungma@eit.uni-kl.de 5212027Sjungma@eit.uni-kl.de 5312027Sjungma@eit.uni-kl.de// ---------------------------------------------------------------------------- 5412027Sjungma@eit.uni-kl.de// CLASS : sc_cor_qt 5512027Sjungma@eit.uni-kl.de// 5612027Sjungma@eit.uni-kl.de// Coroutine class implemented with QuickThreads. 5712027Sjungma@eit.uni-kl.de// ---------------------------------------------------------------------------- 5812027Sjungma@eit.uni-kl.de 5912027Sjungma@eit.uni-kl.de// switch stack protection on/off 6012027Sjungma@eit.uni-kl.de 6112027Sjungma@eit.uni-kl.devoid 6212027Sjungma@eit.uni-kl.desc_cor_qt::stack_protect( bool enable ) 6312027Sjungma@eit.uni-kl.de{ 6412027Sjungma@eit.uni-kl.de // Code needs to be tested on HP-UX and disabled if it doesn't work there 6512027Sjungma@eit.uni-kl.de // Code still needs to be ported to WIN32 6612027Sjungma@eit.uni-kl.de 6712027Sjungma@eit.uni-kl.de static std::size_t pagesize; 6812027Sjungma@eit.uni-kl.de 6912027Sjungma@eit.uni-kl.de if( pagesize == 0 ) { 7012027Sjungma@eit.uni-kl.de# if defined(__ppc__) 7112027Sjungma@eit.uni-kl.de pagesize = getpagesize(); 7212027Sjungma@eit.uni-kl.de# else 7312027Sjungma@eit.uni-kl.de pagesize = sysconf( _SC_PAGESIZE ); 7412027Sjungma@eit.uni-kl.de# endif 7512027Sjungma@eit.uni-kl.de } 7612027Sjungma@eit.uni-kl.de 7712027Sjungma@eit.uni-kl.de assert( pagesize != 0 ); 7812027Sjungma@eit.uni-kl.de assert( m_stack_size > ( 2 * pagesize ) ); 7912027Sjungma@eit.uni-kl.de 8012027Sjungma@eit.uni-kl.de#ifdef QUICKTHREADS_GROW_DOWN 8112027Sjungma@eit.uni-kl.de // Stacks grow from high address down to low address 8212027Sjungma@eit.uni-kl.de caddr_t redzone = caddr_t( ( ( std::size_t( m_stack ) + pagesize - 1 ) / 8312027Sjungma@eit.uni-kl.de pagesize ) * pagesize ); 8412027Sjungma@eit.uni-kl.de#else 8512027Sjungma@eit.uni-kl.de // Stacks grow from low address up to high address 8612027Sjungma@eit.uni-kl.de caddr_t redzone = caddr_t( ( ( std::size_t( m_stack ) + 8712027Sjungma@eit.uni-kl.de m_stack_size - pagesize ) / 8812027Sjungma@eit.uni-kl.de pagesize ) * pagesize ); 8912027Sjungma@eit.uni-kl.de#endif 9012027Sjungma@eit.uni-kl.de 9112027Sjungma@eit.uni-kl.de int ret; 9212027Sjungma@eit.uni-kl.de 9312027Sjungma@eit.uni-kl.de // Enable the red zone at the end of the stack so that references within 9412027Sjungma@eit.uni-kl.de // it will cause an interrupt. 9512027Sjungma@eit.uni-kl.de 9612027Sjungma@eit.uni-kl.de if( enable ) { 9712027Sjungma@eit.uni-kl.de ret = mprotect( redzone, pagesize - 1, PROT_NONE ); 9812027Sjungma@eit.uni-kl.de } 9912027Sjungma@eit.uni-kl.de 10012027Sjungma@eit.uni-kl.de // Revert the red zone to normal memory usage. Try to make it read - write - 10112027Sjungma@eit.uni-kl.de // execute. If that does not work then settle for read - write 10212027Sjungma@eit.uni-kl.de 10312027Sjungma@eit.uni-kl.de else { 10412027Sjungma@eit.uni-kl.de ret = mprotect( redzone, pagesize - 1, PROT_READ|PROT_WRITE|PROT_EXEC); 10512027Sjungma@eit.uni-kl.de if ( ret != 0 ) 10612027Sjungma@eit.uni-kl.de ret = mprotect( redzone, pagesize - 1, PROT_READ | PROT_WRITE ); 10712027Sjungma@eit.uni-kl.de } 10812027Sjungma@eit.uni-kl.de 10912027Sjungma@eit.uni-kl.de assert( ret == 0 ); 11012027Sjungma@eit.uni-kl.de} 11112027Sjungma@eit.uni-kl.de 11212027Sjungma@eit.uni-kl.de 11312027Sjungma@eit.uni-kl.de// ---------------------------------------------------------------------------- 11412027Sjungma@eit.uni-kl.de// CLASS : sc_cor_pkg_qt 11512027Sjungma@eit.uni-kl.de// 11612027Sjungma@eit.uni-kl.de// Coroutine package class implemented with QuickThreads. 11712027Sjungma@eit.uni-kl.de// ---------------------------------------------------------------------------- 11812027Sjungma@eit.uni-kl.de 11912027Sjungma@eit.uni-kl.deint sc_cor_pkg_qt::instance_count = 0; 12012027Sjungma@eit.uni-kl.de 12112027Sjungma@eit.uni-kl.de 12212027Sjungma@eit.uni-kl.de// support function 12312027Sjungma@eit.uni-kl.de 12412027Sjungma@eit.uni-kl.deinline 12512027Sjungma@eit.uni-kl.devoid* 12612027Sjungma@eit.uni-kl.destack_align( void* sp, int alignment, std::size_t* stack_size ) 12712027Sjungma@eit.uni-kl.de{ 12812027Sjungma@eit.uni-kl.de int round_up_mask = alignment - 1; 12912027Sjungma@eit.uni-kl.de *stack_size = (*stack_size + round_up_mask) & ~round_up_mask; 13012027Sjungma@eit.uni-kl.de return ( (void*)(((qt_word_t) sp + round_up_mask) & ~round_up_mask) ); 13112027Sjungma@eit.uni-kl.de} 13212027Sjungma@eit.uni-kl.de 13312027Sjungma@eit.uni-kl.de 13412027Sjungma@eit.uni-kl.de// constructor 13512027Sjungma@eit.uni-kl.de 13612027Sjungma@eit.uni-kl.desc_cor_pkg_qt::sc_cor_pkg_qt( sc_simcontext* simc ) 13712027Sjungma@eit.uni-kl.de: sc_cor_pkg( simc ) 13812027Sjungma@eit.uni-kl.de{ 13912027Sjungma@eit.uni-kl.de if( ++ instance_count == 1 ) { 14012027Sjungma@eit.uni-kl.de // initialize the current coroutine 14112027Sjungma@eit.uni-kl.de assert( curr_cor == 0 ); 14212027Sjungma@eit.uni-kl.de curr_cor = &main_cor; 14312027Sjungma@eit.uni-kl.de } 14412027Sjungma@eit.uni-kl.de} 14512027Sjungma@eit.uni-kl.de 14612027Sjungma@eit.uni-kl.de 14712027Sjungma@eit.uni-kl.de// destructor 14812027Sjungma@eit.uni-kl.de 14912027Sjungma@eit.uni-kl.desc_cor_pkg_qt::~sc_cor_pkg_qt() 15012027Sjungma@eit.uni-kl.de{ 15112027Sjungma@eit.uni-kl.de if( -- instance_count == 0 ) { 15212027Sjungma@eit.uni-kl.de // cleanup the current coroutine 15312027Sjungma@eit.uni-kl.de curr_cor = 0; 15412027Sjungma@eit.uni-kl.de } 15512027Sjungma@eit.uni-kl.de} 15612027Sjungma@eit.uni-kl.de 15712027Sjungma@eit.uni-kl.de 15812027Sjungma@eit.uni-kl.de// create a new coroutine 15912027Sjungma@eit.uni-kl.de 16012027Sjungma@eit.uni-kl.deextern "C" 16112027Sjungma@eit.uni-kl.devoid 16212027Sjungma@eit.uni-kl.desc_cor_qt_wrapper( void* arg, void* cor, qt_userf_t* fn ) 16312027Sjungma@eit.uni-kl.de{ 16412027Sjungma@eit.uni-kl.de curr_cor = RCAST<sc_cor_qt*>( cor ); 16512027Sjungma@eit.uni-kl.de // invoke the user function 16612027Sjungma@eit.uni-kl.de (*(sc_cor_fn*) fn)( arg ); 16712027Sjungma@eit.uni-kl.de // not reached 16812027Sjungma@eit.uni-kl.de} 16912027Sjungma@eit.uni-kl.de 17012027Sjungma@eit.uni-kl.desc_cor* 17112027Sjungma@eit.uni-kl.desc_cor_pkg_qt::create( std::size_t stack_size, sc_cor_fn* fn, void* arg ) 17212027Sjungma@eit.uni-kl.de{ 17312027Sjungma@eit.uni-kl.de sc_cor_qt* cor = new sc_cor_qt(); 17412027Sjungma@eit.uni-kl.de cor->m_pkg = this; 17512027Sjungma@eit.uni-kl.de cor->m_stack_size = stack_size; 17612027Sjungma@eit.uni-kl.de cor->m_stack = new char[cor->m_stack_size]; 17712027Sjungma@eit.uni-kl.de void* sto = stack_align( cor->m_stack, QUICKTHREADS_STKALIGN, 17812027Sjungma@eit.uni-kl.de &cor->m_stack_size ); 17912027Sjungma@eit.uni-kl.de cor->m_sp = QUICKTHREADS_SP(sto, cor->m_stack_size - QUICKTHREADS_STKALIGN); 18012027Sjungma@eit.uni-kl.de cor->m_sp = QUICKTHREADS_ARGS( cor->m_sp, arg, cor, (qt_userf_t*) fn, 18112027Sjungma@eit.uni-kl.de sc_cor_qt_wrapper ); 18212027Sjungma@eit.uni-kl.de return cor; 18312027Sjungma@eit.uni-kl.de} 18412027Sjungma@eit.uni-kl.de 18512027Sjungma@eit.uni-kl.de 18612027Sjungma@eit.uni-kl.de// yield to the next coroutine 18712027Sjungma@eit.uni-kl.de 18812027Sjungma@eit.uni-kl.deextern "C" 18912027Sjungma@eit.uni-kl.devoid* 19012027Sjungma@eit.uni-kl.desc_cor_qt_yieldhelp( qt_t* sp, void* old_cor, void* ) 19112027Sjungma@eit.uni-kl.de{ 19212027Sjungma@eit.uni-kl.de RCAST<sc_cor_qt*>( old_cor )->m_sp = sp; 19312027Sjungma@eit.uni-kl.de return 0; 19412027Sjungma@eit.uni-kl.de} 19512027Sjungma@eit.uni-kl.de 19612027Sjungma@eit.uni-kl.devoid 19712027Sjungma@eit.uni-kl.desc_cor_pkg_qt::yield( sc_cor* next_cor ) 19812027Sjungma@eit.uni-kl.de{ 19912027Sjungma@eit.uni-kl.de sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor ); 20012027Sjungma@eit.uni-kl.de sc_cor_qt* old_cor = curr_cor; 20112027Sjungma@eit.uni-kl.de curr_cor = new_cor; 20212027Sjungma@eit.uni-kl.de QUICKTHREADS_BLOCK( sc_cor_qt_yieldhelp, old_cor, 0, new_cor->m_sp ); 20312027Sjungma@eit.uni-kl.de} 20412027Sjungma@eit.uni-kl.de 20512027Sjungma@eit.uni-kl.de 20612027Sjungma@eit.uni-kl.de// abort the current coroutine (and resume the next coroutine) 20712027Sjungma@eit.uni-kl.de 20812027Sjungma@eit.uni-kl.deextern "C" 20912027Sjungma@eit.uni-kl.devoid* 21012027Sjungma@eit.uni-kl.desc_cor_qt_aborthelp( qt_t*, void*, void* ) 21112027Sjungma@eit.uni-kl.de{ 21212027Sjungma@eit.uni-kl.de return 0; 21312027Sjungma@eit.uni-kl.de} 21412027Sjungma@eit.uni-kl.de 21512027Sjungma@eit.uni-kl.devoid 21612027Sjungma@eit.uni-kl.desc_cor_pkg_qt::abort( sc_cor* next_cor ) 21712027Sjungma@eit.uni-kl.de{ 21812027Sjungma@eit.uni-kl.de sc_cor_qt* new_cor = SCAST<sc_cor_qt*>( next_cor ); 21912027Sjungma@eit.uni-kl.de sc_cor_qt* old_cor = curr_cor; 22012027Sjungma@eit.uni-kl.de curr_cor = new_cor; 22112027Sjungma@eit.uni-kl.de QUICKTHREADS_ABORT( sc_cor_qt_aborthelp, old_cor, 0, new_cor->m_sp ); 22212027Sjungma@eit.uni-kl.de} 22312027Sjungma@eit.uni-kl.de 22412027Sjungma@eit.uni-kl.de 22512027Sjungma@eit.uni-kl.de// get the main coroutine 22612027Sjungma@eit.uni-kl.de 22712027Sjungma@eit.uni-kl.desc_cor* 22812027Sjungma@eit.uni-kl.desc_cor_pkg_qt::get_main() 22912027Sjungma@eit.uni-kl.de{ 23012027Sjungma@eit.uni-kl.de return &main_cor; 23112027Sjungma@eit.uni-kl.de} 23212027Sjungma@eit.uni-kl.de 23312027Sjungma@eit.uni-kl.de} // namespace sc_core 23412027Sjungma@eit.uni-kl.de 23512027Sjungma@eit.uni-kl.de#endif 23612027Sjungma@eit.uni-kl.de 23712027Sjungma@eit.uni-kl.de// $Log: sc_cor_qt.cpp,v $ 23812027Sjungma@eit.uni-kl.de// Revision 1.9 2011/08/29 18:04:32 acg 23912027Sjungma@eit.uni-kl.de// Philipp A. Hartmann: miscellaneous clean ups. 24012027Sjungma@eit.uni-kl.de// 24112027Sjungma@eit.uni-kl.de// Revision 1.8 2011/08/26 20:46:09 acg 24212027Sjungma@eit.uni-kl.de// Andy Goodrich: moved the modification log to the end of the file to 24312027Sjungma@eit.uni-kl.de// eliminate source line number skew when check-ins are done. 24412027Sjungma@eit.uni-kl.de// 24512027Sjungma@eit.uni-kl.de// Revision 1.7 2011/02/18 20:27:14 acg 24612027Sjungma@eit.uni-kl.de// Andy Goodrich: Updated Copyrights. 24712027Sjungma@eit.uni-kl.de// 24812027Sjungma@eit.uni-kl.de// Revision 1.6 2011/02/13 21:47:37 acg 24912027Sjungma@eit.uni-kl.de// Andy Goodrich: update copyright notice. 25012027Sjungma@eit.uni-kl.de// 25112027Sjungma@eit.uni-kl.de// Revision 1.5 2010/08/03 16:52:14 acg 25212027Sjungma@eit.uni-kl.de// Andy Goodrich: line formatting. 25312027Sjungma@eit.uni-kl.de// 25412027Sjungma@eit.uni-kl.de// Revision 1.4 2008/11/11 14:03:07 acg 25512027Sjungma@eit.uni-kl.de// Andy Goodrich: added execute access to the release of red zone storage 25612027Sjungma@eit.uni-kl.de// per Ulli's suggestion. 25712027Sjungma@eit.uni-kl.de// 25812027Sjungma@eit.uni-kl.de// Revision 1.3 2008/05/22 17:06:25 acg 25912027Sjungma@eit.uni-kl.de// Andy Goodrich: updated copyright notice to include 2008. 26012027Sjungma@eit.uni-kl.de// 26112027Sjungma@eit.uni-kl.de// Revision 1.2 2008/03/24 18:32:36 acg 26212027Sjungma@eit.uni-kl.de// Andy Goodrich: added include of sys/types.h to pick up the declaration 26312027Sjungma@eit.uni-kl.de// of caddr_t. 26412027Sjungma@eit.uni-kl.de// 26512027Sjungma@eit.uni-kl.de// Revision 1.1.1.1 2006/12/15 20:20:05 acg 26612027Sjungma@eit.uni-kl.de// SystemC 2.3 26712027Sjungma@eit.uni-kl.de// 26812027Sjungma@eit.uni-kl.de// Revision 1.3 2006/01/13 18:44:29 acg 26912027Sjungma@eit.uni-kl.de// Added $Log to record CVS changes into the source. 27012027Sjungma@eit.uni-kl.de 27112027Sjungma@eit.uni-kl.de// Taf! 272