Changeset 9b443c7f for src/Concurrency


Ignore:
Timestamp:
Mar 15, 2017, 5:02:25 PM (9 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, stuck-waitfor-destruct, with_gc
Children:
f2e40a9f
Parents:
5a3ac84 (diff), 29f44a74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/Concurrency
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r5a3ac84 r9b443c7f  
     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[] = { get_monitor(a), get_monitor(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                virtual void visit(   StructDecl *functionDecl ) override final;
     101
     102                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     103                void validate( DeclarationWithType * );
     104                void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);
     105
     106                static void implement( std::list< Declaration * > & translationUnit ) {
     107                        MutexKeyword impl;
     108                        acceptAll( translationUnit, impl );
     109                }
     110
     111          private:
     112                StructDecl* monitor_decl = nullptr;
     113        };
     114
     115        //=============================================================================================
     116        // General entry routine
     117        //=============================================================================================
     118        void applyKeywords( std::list< Declaration * > & translationUnit ) {
     119                ThreadKeyword   ::implement( translationUnit );
     120                CoroutineKeyword        ::implement( translationUnit );
     121                MonitorKeyword  ::implement( translationUnit );
     122                MutexKeyword    ::implement( translationUnit );
     123        }
     124
     125        //=============================================================================================
     126        // Mutex keyword implementation
     127        //=============================================================================================
     128        void MutexKeyword::visit(FunctionDecl* decl) {
     129                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
     130                if( mutexArgs.empty() ) return;
     131
     132                for(auto arg : mutexArgs) {
     133                        validate( arg );
     134                }
     135
     136                CompoundStmt* body = decl->get_statements();
     137                if( ! body ) return;
     138
     139                assert(monitor_decl);
     140                addStatments( body, mutexArgs );
     141        }
     142
     143        void MutexKeyword::visit(StructDecl* decl) {
     144                if( decl->get_name() == "monitor_desc" ) {
     145                        assert( !monitor_decl );
     146                        monitor_decl = decl;
     147                }
     148        }
     149
     150        std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
     151                std::list<DeclarationWithType*> mutexArgs;
     152
     153                for( auto arg : decl->get_functionType()->get_parameters()) {
     154                        //Find mutex arguments
     155                        Type* ty = arg->get_type();
     156                        if( ! ty->get_qualifiers().isMutex ) continue;
     157
     158                        //Append it to the list
     159                        mutexArgs.push_back( arg );
     160                }
     161
     162                return mutexArgs;
     163        }
     164
     165        void MutexKeyword::validate( DeclarationWithType * arg ) {
     166                Type* ty = arg->get_type();
     167
     168                //Makes sure it's not a copy
     169                PointerType* pty = dynamic_cast< PointerType * >( ty );
     170                if( ! pty ) throw SemanticError( "Mutex argument must be of pointer/reference type ", arg );
     171
     172                //Make sure the we are pointing directly to a type
     173                Type* base = pty->get_base();
     174                if(  dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
     175
     176                //Make sure that typed isn't mutex
     177                if( ! base->get_qualifiers().isMutex ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     178        }
     179
     180        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     181
     182                ObjectDecl * monitors = new ObjectDecl(
     183                        "__monitors",
     184                        noStorage,
     185                        LinkageSpec::Cforall,
     186                        nullptr,
     187                        new ArrayType(
     188                                noQualifiers,
     189                                new PointerType(
     190                                        noQualifiers,
     191                                        new StructInstType(
     192                                                noQualifiers,
     193                                                monitor_decl
     194                                        )
     195                                ),
     196                                new ConstantExpr( Constant::from_ulong( args.size() ) ),
     197                                false,
     198                                false
     199                        ),
     200                        new ListInit(
     201                                map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){
     202                                        return new SingleInit( new UntypedExpr(
     203                                                new NameExpr( "get_monitor" ),
     204                                                {  new VariableExpr( var ) }
     205                                        ) );
     206                                })
     207                        )
     208                );
     209
     210                //in reverse order :
     211                // monitor_guard_t __guard = { __monitors, # };
     212                body->push_front(
     213                        new DeclStmt( noLabels, new ObjectDecl(
     214                                "__guard",
     215                                noStorage,
     216                                LinkageSpec::Cforall,
     217                                nullptr,
     218                                new StructInstType(
     219                                        noQualifiers,
     220                                        "monitor_guard_t"
     221                                ),
     222                                new ListInit(
     223                                        {
     224                                                new SingleInit( new VariableExpr( monitors ) ),
     225                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
     226                                        }
     227                                )
     228                        ))
     229                );
     230
     231                //monitor_desc * __monitors[] = { a, b };
     232                body->push_front( new DeclStmt( noLabels, monitors) );
     233        }
     234};
  • src/Concurrency/Keywords.h

    r5a3ac84 r9b443c7f  
     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.h --
     9//
     10// Author           : Thierry Delisle
     11// Created On       : Fri Mar 10 15:16:42 2017
     12// Last Modified By :
     13// Last Modified On :
     14// Update Count     : 0
     15//
     16
     17#ifndef KEYWORDS_H
     18#define KEYWORDS_H
     19
     20#include <list>
     21
     22#include "SynTree/Declaration.h"
     23
     24namespace Concurrency {
     25        void applyKeywords( std::list< Declaration * > & translationUnit );
     26};
     27
     28#endif //KEYWORDS_H
Note: See TracChangeset for help on using the changeset viewer.