Ignore:
Timestamp:
Mar 14, 2017, 11:14:53 AM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
026bb82
Parents:
c54b0b4
Message:

Added first implementation of mutex keyword

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    rc54b0b4 r64adb03  
     1//                              -*- Mode: CPP -*-
     2//
     3// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     4//
     5// The contents of this file are covered under the licence agreement in the
     6// file "LICENCE" distributed with Cforall.
     7//
     8// Keywords.cc --
     9//
     10// Author           : Thierry Delisle
     11// Created On       : Mon Mar 13 12:41:22 2017
     12// Last Modified By :
     13// Last Modified On :
     14// Update Count     : 0
     15//
     16
     17#include "Concurrency/Keywords.h"
     18
     19#include "SynTree/Declaration.h"
     20#include "SynTree/Expression.h"
     21#include "SynTree/Initializer.h"
     22#include "SynTree/Mutator.h"
     23#include "SynTree/Statement.h"
     24#include "SynTree/Type.h"
     25#include "SynTree/Visitor.h"
     26
     27namespace Concurrency {
     28
     29        namespace {
     30                const std::list<Label> noLabels;
     31                DeclarationNode::StorageClasses noStorage;
     32                Type::Qualifiers noQualifiers;
     33        }
     34
     35        //=============================================================================================
     36        // Visitors declaration
     37        //=============================================================================================
     38
     39        //-----------------------------------------------------------------------------
     40        //Handles thread type declarations :
     41        // thread Mythread {                         struct MyThread {
     42        //      int data;                                  int data;
     43        //      a_struct_t more_data;                      a_struct_t more_data;
     44        //                                =>             thread_desc __thrd_d;
     45        // };                                        };
     46        //                                           static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; }
     47        //                                           void main( MyThread * this );
     48        //
     49        class ThreadKeyword final : public Mutator {
     50          public:
     51
     52                static void implement( std::list< Declaration * > & translationUnit ) {}
     53        };
     54
     55        //-----------------------------------------------------------------------------
     56        //Handles coroutine type declarations :
     57        // coroutine MyCoroutine {                   struct MyCoroutine {
     58        //      int data;                                  int data;
     59        //      a_struct_t more_data;                      a_struct_t more_data;
     60        //                                =>             coroutine_desc __cor_d;
     61        // };                                        };
     62        //                                           static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
     63        //                                           void main( MyCoroutine * this );
     64        //
     65        class CoroutineKeyword final : public Mutator {
     66          public:
     67
     68                static void implement( std::list< Declaration * > & translationUnit ) {}
     69        };
     70
     71        //-----------------------------------------------------------------------------
     72        //Handles monitor type declarations :
     73        // monitor MyMonitor {                       struct MyMonitor {
     74        //      int data;                                  int data;
     75        //      a_struct_t more_data;                      a_struct_t more_data;
     76        //                                =>             monitor_desc __mon_d;
     77        // };                                        };
     78        //                                           static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
     79        //                                           void main( MyMonitor * this );
     80        //
     81        class MonitorKeyword final : public Mutator {
     82          public:
     83
     84                static void implement( std::list< Declaration * > & translationUnit ) {}
     85        };
     86
     87        //-----------------------------------------------------------------------------
     88        //Handles mutex routines definitions :
     89        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
     90        //                                                                       monitor_desc * __monitors[] = { a, b };
     91        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
     92        //    /*Some code*/                                       =>           /*Some code*/
     93        // }                                                               }
     94        //
     95        class MutexKeyword final : public Visitor {
     96          public:
     97
     98                using Visitor::visit;
     99                virtual void visit( FunctionDecl *functionDecl ) override final;
     100
     101                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     102                void validate( DeclarationWithType * );
     103                void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);
     104
     105                static void implement( std::list< Declaration * > & translationUnit ) {
     106                        MutexKeyword impl;
     107                        acceptAll( translationUnit, impl );
     108                }
     109        };
     110
     111        //=============================================================================================
     112        // General entry routine
     113        //=============================================================================================
     114        void applyKeywords( std::list< Declaration * > & translationUnit ) {
     115                ThreadKeyword   ::implement( translationUnit );
     116                CoroutineKeyword        ::implement( translationUnit );
     117                MonitorKeyword  ::implement( translationUnit );
     118                MutexKeyword    ::implement( translationUnit );
     119        }
     120
     121        //=============================================================================================
     122        // Mutex keyword implementation
     123        //=============================================================================================
     124        void MutexKeyword::visit(FunctionDecl* decl) {
     125                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
     126                if( mutexArgs.empty() ) return;
     127
     128                for(auto arg : mutexArgs) {
     129                        validate( arg );
     130                }
     131
     132                CompoundStmt* body = decl->get_statements();
     133                if( ! body ) return;
     134
     135                addStatments( body, mutexArgs );
     136        }
     137
     138        std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
     139                std::list<DeclarationWithType*> mutexArgs;
     140
     141                for( auto arg : decl->get_functionType()->get_parameters()) {
     142                        //Find mutex arguments
     143                        Type* ty = arg->get_type();
     144                        if( ! ty->get_qualifiers().isMutex ) continue;
     145
     146                        //Append it to the list
     147                        mutexArgs.push_back( arg );
     148                }
     149
     150                return mutexArgs;
     151        }
     152
     153        void MutexKeyword::validate( DeclarationWithType * arg ) {
     154                Type* ty = arg->get_type();
     155
     156                //Makes sure it's not a copy
     157                PointerType* pty = dynamic_cast< PointerType * >( ty );
     158                if( ! pty ) throw SemanticError( "Mutex argument must be of pointer/reference type ", arg );
     159
     160                //Make sure the we are pointing directly to a type
     161                Type* base = pty->get_base();
     162                if(  dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
     163
     164                //Make sure that typed isn't mutex
     165                if( ! base->get_qualifiers().isMutex ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     166        }
     167
     168        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     169                //in reverse order :
     170                // monitor_guard_t __guard = { __monitors, # };
     171                body->push_front(
     172                        new DeclStmt( noLabels, new ObjectDecl(
     173                                "__guard",
     174                                noStorage,
     175                                LinkageSpec::Cforall,
     176                                nullptr,
     177                                new StructInstType(
     178                                        noQualifiers,
     179                                        "monitor_guard_t"
     180                                ),
     181                                new ListInit(
     182                                        {
     183                                                new SingleInit( new NameExpr( "__monitors" ) ),
     184                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
     185                                        }
     186                                )
     187                        ))
     188                );
     189
     190                //monitor_desc * __monitors[] = { a, b };
     191                body->push_front(
     192                        new DeclStmt( noLabels, new ObjectDecl(
     193                                "__monitors",
     194                                noStorage,
     195                                LinkageSpec::Cforall,
     196                                nullptr,
     197                                new ArrayType(
     198                                        noQualifiers,
     199                                        new PointerType(
     200                                                noQualifiers,
     201                                                new StructInstType(
     202                                                        noQualifiers,
     203                                                        "monitor_desc"
     204                                                )
     205                                        ),
     206                                        new ConstantExpr( Constant::from_ulong( args.size() ) ),
     207                                        false,
     208                                        false
     209                                ),
     210                                new ListInit(
     211                                        map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){
     212                                                return new SingleInit( new VariableExpr( var ) );
     213                                        })
     214                                )
     215                        ))
     216                );
     217        }
     218};
Note: See TracChangeset for help on using the changeset viewer.