| 160 | | 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. |
| 161 | | |
| 162 | | 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`. |
| | 160 | For each shared variable `v`, a thread has a local copy of '_v' and a local status variable`v_state` (both are implemented as part of $omp_shared). `_v` has the same type as `v`. 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 thread private scope. |
| | 161 | |
| | 162 | For example, given a shared variable `a`, there will be: |
| | 163 | |
| | 164 | shared copy of variable: |
| | 165 | `double a[N]; // declared in shared scope` |
| | 166 | |
| | 167 | local copy of variable: |
| | 168 | `double a_local[N]; // declared in thread-local scope` |
| | 169 | |
| | 170 | local status variable: |
| | 171 | `int a_status[N]; // declared in thread-local scope` |
| | 172 | |
| | 173 | interepration of status value: |
| | 174 | '0=EMPTY': local is empty |
| | 175 | '1=FULL': local is occupied, no writes to it have been made |
| | 176 | '2=MODIFIED': local is occupied, writes have been made to it |
| | 177 | |
| | 178 | Initially: `local=shared`, `status=FULL` |
| 167 | | * 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. |
| 168 | | * if the state value is tid, do the write to the local copy. |
| 169 | | * 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. |
| 170 | | |
| 171 | | A read from (some part of) the shared variable by thread tid: |
| 172 | | * 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.) |
| 173 | | * if the state value is tid, read your local copy. |
| 174 | | * 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. |
| | 195 | * write the data to the local copy; |
| | 196 | * update the status to `MODIFIED`. |
| | 197 | {{{ |
| | 198 | write (ptr into a_local[i]): |
| | 199 | write to a_local[i]; |
| | 200 | set a_status[i] to MODIFIED; |
| | 201 | }}} |
| 177 | | * if the state value is -1: copy the global value to your local copy of the variable. |
| 178 | | * if the state value is tid: copy your local value to the global copy of the variable and set the state value to -1. |
| 179 | | * 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. |
| | 204 | * if the status value is `EMPTY`: no op; |
| | 205 | * if the status value is `FULL`: updates the status to `EMPTY`, sets local copy to default value; |
| | 206 | * if the status value is `MODIFIED`: copies the local copy to the shared copy, updates the status to `EMPTY`, sets local copy to default value. |
| | 207 | {{{ |
| | 208 | flush (some set of memory units): |
| | 209 | for each memory unit specified: |
| | 210 | switch (status) { |
| | 211 | case EMPTY: |
| | 212 | break; // nothing to do |
| | 213 | case MODIFIED: |
| | 214 | copy local to shared; |
| | 215 | case FULL: |
| | 216 | set status to EMPTY; |
| | 217 | set local to default value; |
| | 218 | break; |
| | 219 | } |
| | 220 | }}} |