#include "AST.h" #include "CodeContext.h" #include "CtExternal.h" #include "CtMonitor.h" #include "CtGlobal.h" #include "CtLocal.h" #include "UniqueId.h" #include "lgMacro.h" //////////////////////////////////////////////////////////////////////// // // generic support for fetching monitors // UniqueId MonitorFetchNode::generator( "monitor" ); void MonitorFetchNode::resetGenerator() { generator.reset(); } void MonitorFetchNode::declareHolder( CodeContext &context ) const { static const CtExternal monitor( CtMonitor::singleton ); static const CtLocal localMonitor( monitor ); static const CtGlobal globalMonitor( monitor ); static const CtGlobal globalLocalMonitor( localMonitor ); context.declare( holder(), globalMonitor ); } const string &MonitorFetchNode::holder() const { if (_holder.empty()) _holder = generator.next(); return _holder; } //////////////////////////////////////////////////////////////////////// // // specific logic for fetching class and instance monitors // void MonitorFetchClassNode::emitStatement( CodeContext &context ) { declareHolder( context ); assert(decl()->category() & Decl::Class); ClassDecl *cd = static_cast< ClassDecl *>(decl()); context << "MONITOR_FETCH_CLASS(" << cd->cStaticFieldsStructName() << ", " << holder() << ");" << endCline; } void MonitorFetchInstanceNode::emitStatement( CodeContext &context ) { declareHolder( context ); const string mutex = expr()->emitExpression( context ); context << lgMacro( "MONITOR_FETCH_INSTANCE", *expr()->type() ) << '(' << holder() << ", " << mutex << ");" << endCline; } //////////////////////////////////////////////////////////////////////// // // acquiring and releasing locks // void MonitorLockNode::emitStatement( CodeContext &context ) { const string &holder = fetcher()->holder(); context << "MONITOR_LOCK(" << holder << ");" << endCline; } void MonitorUnlockNode::emitStatement( CodeContext &context ) { const string &holder = fetcher()->holder(); context << "MONITOR_UNLOCK(" << holder << ");" << endCline; }