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