Home | History | Annotate | Download | only in thread.lock.algorithm
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // <mutex>
     11 
     12 // template <class L1, class L2, class... L3>
     13 //   void lock(L1&, L2&, L3&...);
     14 
     15 #include <mutex>
     16 #include <cassert>
     17 
     18 class L0
     19 {
     20     bool locked_;
     21 
     22 public:
     23     L0() : locked_(false) {}
     24 
     25     void lock()
     26     {
     27         locked_ = true;
     28     }
     29 
     30     bool try_lock()
     31     {
     32         locked_ = true;
     33         return locked_;
     34     }
     35 
     36     void unlock() {locked_ = false;}
     37 
     38     bool locked() const {return locked_;}
     39 };
     40 
     41 class L1
     42 {
     43     bool locked_;
     44 
     45 public:
     46     L1() : locked_(false) {}
     47 
     48     void lock()
     49     {
     50         locked_ = true;
     51     }
     52 
     53     bool try_lock()
     54     {
     55         locked_ = false;
     56         return locked_;
     57     }
     58 
     59     void unlock() {locked_ = false;}
     60 
     61     bool locked() const {return locked_;}
     62 };
     63 
     64 class L2
     65 {
     66     bool locked_;
     67 
     68 public:
     69     L2() : locked_(false) {}
     70 
     71     void lock()
     72     {
     73         throw 1;
     74     }
     75 
     76     bool try_lock()
     77     {
     78         throw 1;
     79         return locked_;
     80     }
     81 
     82     void unlock() {locked_ = false;}
     83 
     84     bool locked() const {return locked_;}
     85 };
     86 
     87 int main()
     88 {
     89     {
     90         L0 l0;
     91         L0 l1;
     92         std::lock(l0, l1);
     93         assert(l0.locked());
     94         assert(l1.locked());
     95     }
     96     {
     97         L0 l0;
     98         L1 l1;
     99         std::lock(l0, l1);
    100         assert(l0.locked());
    101         assert(l1.locked());
    102     }
    103     {
    104         L1 l0;
    105         L0 l1;
    106         std::lock(l0, l1);
    107         assert(l0.locked());
    108         assert(l1.locked());
    109     }
    110     {
    111         L0 l0;
    112         L2 l1;
    113         try
    114         {
    115             std::lock(l0, l1);
    116             assert(false);
    117         }
    118         catch (int)
    119         {
    120             assert(!l0.locked());
    121             assert(!l1.locked());
    122         }
    123     }
    124     {
    125         L2 l0;
    126         L0 l1;
    127         try
    128         {
    129             std::lock(l0, l1);
    130             assert(false);
    131         }
    132         catch (int)
    133         {
    134             assert(!l0.locked());
    135             assert(!l1.locked());
    136         }
    137     }
    138     {
    139         L1 l0;
    140         L2 l1;
    141         try
    142         {
    143             std::lock(l0, l1);
    144             assert(false);
    145         }
    146         catch (int)
    147         {
    148             assert(!l0.locked());
    149             assert(!l1.locked());
    150         }
    151     }
    152     {
    153         L2 l0;
    154         L1 l1;
    155         try
    156         {
    157             std::lock(l0, l1);
    158             assert(false);
    159         }
    160         catch (int)
    161         {
    162             assert(!l0.locked());
    163             assert(!l1.locked());
    164         }
    165     }
    166     {
    167         L2 l0;
    168         L2 l1;
    169         try
    170         {
    171             std::lock(l0, l1);
    172             assert(false);
    173         }
    174         catch (int)
    175         {
    176             assert(!l0.locked());
    177             assert(!l1.locked());
    178         }
    179     }
    180 #ifndef _LIBCPP_HAS_NO_VARIADICS
    181     {
    182         L0 l0;
    183         L0 l1;
    184         L0 l2;
    185         std::lock(l0, l1, l2);
    186         assert(l0.locked());
    187         assert(l1.locked());
    188         assert(l2.locked());
    189     }
    190     {
    191         L2 l0;
    192         L2 l1;
    193         L2 l2;
    194         try
    195         {
    196             std::lock(l0, l1, l2);
    197             assert(false);
    198         }
    199         catch (int)
    200         {
    201             assert(!l0.locked());
    202             assert(!l1.locked());
    203             assert(!l2.locked());
    204         }
    205     }
    206     {
    207         L0 l0;
    208         L0 l1;
    209         L1 l2;
    210         std::lock(l0, l1, l2);
    211         assert(l0.locked());
    212         assert(l1.locked());
    213         assert(l2.locked());
    214     }
    215     {
    216         L0 l0;
    217         L1 l1;
    218         L0 l2;
    219         std::lock(l0, l1, l2);
    220         assert(l0.locked());
    221         assert(l1.locked());
    222         assert(l2.locked());
    223     }
    224     {
    225         L1 l0;
    226         L0 l1;
    227         L0 l2;
    228         std::lock(l0, l1, l2);
    229         assert(l0.locked());
    230         assert(l1.locked());
    231         assert(l2.locked());
    232     }
    233     {
    234         L0 l0;
    235         L0 l1;
    236         L2 l2;
    237         try
    238         {
    239             std::lock(l0, l1, l2);
    240             assert(false);
    241         }
    242         catch (int)
    243         {
    244             assert(!l0.locked());
    245             assert(!l1.locked());
    246             assert(!l2.locked());
    247         }
    248     }
    249     {
    250         L0 l0;
    251         L2 l1;
    252         L0 l2;
    253         try
    254         {
    255             std::lock(l0, l1, l2);
    256             assert(false);
    257         }
    258         catch (int)
    259         {
    260             assert(!l0.locked());
    261             assert(!l1.locked());
    262             assert(!l2.locked());
    263         }
    264     }
    265     {
    266         L2 l0;
    267         L0 l1;
    268         L0 l2;
    269         try
    270         {
    271             std::lock(l0, l1, l2);
    272             assert(false);
    273         }
    274         catch (int)
    275         {
    276             assert(!l0.locked());
    277             assert(!l1.locked());
    278             assert(!l2.locked());
    279         }
    280     }
    281     {
    282         L2 l0;
    283         L2 l1;
    284         L0 l2;
    285         try
    286         {
    287             std::lock(l0, l1, l2);
    288             assert(false);
    289         }
    290         catch (int)
    291         {
    292             assert(!l0.locked());
    293             assert(!l1.locked());
    294             assert(!l2.locked());
    295         }
    296     }
    297     {
    298         L2 l0;
    299         L0 l1;
    300         L2 l2;
    301         try
    302         {
    303             std::lock(l0, l1, l2);
    304             assert(false);
    305         }
    306         catch (int)
    307         {
    308             assert(!l0.locked());
    309             assert(!l1.locked());
    310             assert(!l2.locked());
    311         }
    312     }
    313     {
    314         L0 l0;
    315         L2 l1;
    316         L2 l2;
    317         try
    318         {
    319             std::lock(l0, l1, l2);
    320             assert(false);
    321         }
    322         catch (int)
    323         {
    324             assert(!l0.locked());
    325             assert(!l1.locked());
    326             assert(!l2.locked());
    327         }
    328     }
    329     {
    330         L2 l0;
    331         L2 l1;
    332         L1 l2;
    333         try
    334         {
    335             std::lock(l0, l1, l2);
    336             assert(false);
    337         }
    338         catch (int)
    339         {
    340             assert(!l0.locked());
    341             assert(!l1.locked());
    342             assert(!l2.locked());
    343         }
    344     }
    345     {
    346         L2 l0;
    347         L1 l1;
    348         L2 l2;
    349         try
    350         {
    351             std::lock(l0, l1, l2);
    352             assert(false);
    353         }
    354         catch (int)
    355         {
    356             assert(!l0.locked());
    357             assert(!l1.locked());
    358             assert(!l2.locked());
    359         }
    360     }
    361     {
    362         L1 l0;
    363         L2 l1;
    364         L2 l2;
    365         try
    366         {
    367             std::lock(l0, l1, l2);
    368             assert(false);
    369         }
    370         catch (int)
    371         {
    372             assert(!l0.locked());
    373             assert(!l1.locked());
    374             assert(!l2.locked());
    375         }
    376     }
    377     {
    378         L0 l0;
    379         L0 l1;
    380         L0 l2;
    381         L0 l3;
    382         std::lock(l0, l1, l2, l3);
    383         assert(l0.locked());
    384         assert(l1.locked());
    385         assert(l2.locked());
    386         assert(l3.locked());
    387     }
    388     {
    389         L0 l0;
    390         L0 l1;
    391         L0 l2;
    392         L1 l3;
    393         std::lock(l0, l1, l2, l3);
    394         assert(l0.locked());
    395         assert(l1.locked());
    396         assert(l2.locked());
    397         assert(l3.locked());
    398     }
    399     {
    400         L0 l0;
    401         L0 l1;
    402         L1 l2;
    403         L0 l3;
    404         std::lock(l0, l1, l2, l3);
    405         assert(l0.locked());
    406         assert(l1.locked());
    407         assert(l2.locked());
    408         assert(l3.locked());
    409     }
    410     {
    411         L0 l0;
    412         L1 l1;
    413         L0 l2;
    414         L0 l3;
    415         std::lock(l0, l1, l2, l3);
    416         assert(l0.locked());
    417         assert(l1.locked());
    418         assert(l2.locked());
    419         assert(l3.locked());
    420     }
    421     {
    422         L1 l0;
    423         L0 l1;
    424         L0 l2;
    425         L0 l3;
    426         std::lock(l0, l1, l2, l3);
    427         assert(l0.locked());
    428         assert(l1.locked());
    429         assert(l2.locked());
    430         assert(l3.locked());
    431     }
    432     {
    433         L0 l0;
    434         L0 l1;
    435         L0 l2;
    436         L2 l3;
    437         try
    438         {
    439             std::lock(l0, l1, l2, l3);
    440             assert(false);
    441         }
    442         catch (int)
    443         {
    444             assert(!l0.locked());
    445             assert(!l1.locked());
    446             assert(!l2.locked());
    447             assert(!l3.locked());
    448         }
    449     }
    450     {
    451         L0 l0;
    452         L0 l1;
    453         L2 l2;
    454         L0 l3;
    455         try
    456         {
    457             std::lock(l0, l1, l2, l3);
    458             assert(false);
    459         }
    460         catch (int)
    461         {
    462             assert(!l0.locked());
    463             assert(!l1.locked());
    464             assert(!l2.locked());
    465             assert(!l3.locked());
    466         }
    467     }
    468     {
    469         L0 l0;
    470         L2 l1;
    471         L0 l2;
    472         L0 l3;
    473         try
    474         {
    475             std::lock(l0, l1, l2, l3);
    476             assert(false);
    477         }
    478         catch (int)
    479         {
    480             assert(!l0.locked());
    481             assert(!l1.locked());
    482             assert(!l2.locked());
    483             assert(!l3.locked());
    484         }
    485     }
    486     {
    487         L2 l0;
    488         L0 l1;
    489         L0 l2;
    490         L0 l3;
    491         try
    492         {
    493             std::lock(l0, l1, l2, l3);
    494             assert(false);
    495         }
    496         catch (int)
    497         {
    498             assert(!l0.locked());
    499             assert(!l1.locked());
    500             assert(!l2.locked());
    501             assert(!l3.locked());
    502         }
    503     }
    504 #endif  // _LIBCPP_HAS_NO_VARIADICS
    505 }
    506