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