| 54 | | For each shared variable `v` introduce a second variable `v_state`. The type of `v_state` is obtained from the type of `v` by replacing all primitive types (leaf nodes in the type tree) by `int`. Initially all these ints are -1. |
| | 46 | For each shared variable `v` introduce a second variable `v_state`. The type of `v_state` is obtained from the type of `v` by replacing all primitive types (leaf nodes in the type tree) by `int`. Initially all these ints are -1. Both variables are declared in the same, shared, scope. |
| | 47 | |
| | 48 | In addition to the shared variable v, each thread has its own local copy named `_v`, declared in thread private scope. It has the same type as `v`. |
| | 49 | |
| | 50 | Protocols for reads, writes, and flushes: |
| 57 | | * if the state value is -1, set it to tid, then do the write |
| 58 | | * if the state value is tid, do the write |
| 59 | | * else report a data race. |
| | 53 | * if the state value is -1, do the write to the local copy and set the state value to tid. Now thread tid is the "owner" of that memory unit. |
| | 54 | * if the state value is tid, do the write to the local copy. |
| | 55 | * else report a memory model error: you are attempting to write to a variable when some other thread has un-flushed writes to the same variable. The other thread should flush, then you should flush, before doing this write. |
| 62 | | * if the state value is -1 or tid, do the read |
| 63 | | * else report a data race. |
| | 58 | * if the state value is -1, read your local copy and compare it to the global copy. If they differ, report a memory model error: some other thread has modified the variable and flushed, but you did not flush before performing the read. (If you had flushed, your local copy and the shared copy would be equal.) |
| | 59 | * if the state value is tid, read your local copy. |
| | 60 | * else report a memory model error: you are reading from a variable when another thread has un-flushed writes to that variable. The other thread should flush, and then you should flush, before doing this read. |
| 66 | | * if the state value is -1: no-op |
| 67 | | * if the state value is tid: set it to -1 |
| 68 | | * else: some other thread has some write to the variable which it hasn't flushed. But this thread has not done any writes to that variable (since it last flushed). This is a no-op. |
| 69 | | |
| 70 | | Function |
| | 63 | * if the state value is -1: copy the global value to your local copy of the variable. |
| | 64 | * if the state value is tid: copy your local value to the global copy of the variable and set the state value to -1. |
| | 65 | * else: report a memory model error, since you are doing a flush when some other thread has un-flushed writes to the variable. The other thread should flush first. |
| | 66 | |
| | 67 | We will implement the following function, which is implicit in many of the OpenMP constructs: |