| 813 | | In general, reads and writes to shared variables will be processed using the protocols described above. However if the operation occurs within an omp atomic construct, it is translated differently. |
| 814 | | |
| 815 | | TODO: need to look up the rules on the different flavors of atomics. |
| 816 | | |
| 817 | | If sequentially consistent atomic... |
| 818 | | |
| 819 | | If non-sequentially consistent atomic... |
| | 813 | In general, the memory location protected by the atomic construct will be isolated by interacting with local intermediate variables, so that data race on other memory locations not protected by this atomic construct can be checked by CIVL. |
| | 814 | The local intermediate variable is named based on the protected variable identifier, the kind of atomic construct and a counter ID (for separating distinct atomic constructs, which have same `atomic-clause` for a same variable). |
| | 815 | Currently, CIVL only support sequentially consistent atomic operations and will NOT handle non-sequentially consistent ones. |
| | 816 | |
| | 817 | ==== `read` ==== |
| | 818 | |
| | 819 | {{{ |
| | 820 | #pragma omp atomic read |
| | 821 | v = x; // int type |
| | 822 | }}} |
| | 823 | |
| | 824 | => |
| | 825 | |
| | 826 | {{{ |
| | 827 | int $x_read$0; |
| | 828 | $track{ // Will not collect this read on x for checking data race |
| | 829 | $x_read = x; |
| | 830 | } |
| | 831 | v = $x_read$0; |
| | 832 | }}} |
| | 833 | |
| | 834 | ==== `write` ==== |
| | 835 | |
| | 836 | {{{ |
| | 837 | #pragma omp atomic write |
| | 838 | x = EXPR; // int type |
| | 839 | }}} |
| | 840 | |
| | 841 | => |
| | 842 | |
| | 843 | {{{ |
| | 844 | int $x_write$0 = EXPR; |
| | 845 | $track{ // Will not collect this write on x for checking data race |
| | 846 | x = $x_write$0; |
| | 847 | } |
| | 848 | }}} |
| | 849 | |
| | 850 | ==== `update` ==== |
| | 851 | |
| | 852 | {{{ |
| | 853 | #pragma omp atomic update |
| | 854 | x = x BIN_OP EXPR; // int type |
| | 855 | }}} |
| | 856 | |
| | 857 | => |
| | 858 | |
| | 859 | {{{ |
| | 860 | int $x_update$0 = EXPR; |
| | 861 | $track { // Will not collect this update on x for checking data race |
| | 862 | x = x BIN_OP $x_update$0; |
| | 863 | } |
| | 864 | }}} |
| | 865 | |
| | 866 | (All update expression statement can be concluded in this form.) |
| | 867 | |
| | 868 | ==== `capture` ==== |
| | 869 | |
| | 870 | {{{ |
| | 871 | #pragma omp atomic capture |
| | 872 | { |
| | 873 | v = x; // int type |
| | 874 | x = x BIN_OP EXPR; // int type |
| | 875 | } |
| | 876 | }}} |
| | 877 | |
| | 878 | => |
| | 879 | |
| | 880 | {{{ |
| | 881 | int $x_capture$0; |
| | 882 | int $x_capture_delta$0 = EXPR; |
| | 883 | $track { // R/W operations on x will not be collected. |
| | 884 | $x_capture$0 = x; |
| | 885 | x = x BIN_OP $x_capture_delta$0; |
| | 886 | } |
| | 887 | v = $x_capture$0; |
| | 888 | }}} |
| | 889 | |
| | 890 | (The order of the assignment statement of `$x_capture` and the update |
| | 891 | expression statement is corresponding to the order in source code.) |