| | 209 | |
| | 210 | - Barrier |
| | 211 | |
| | 212 | {{{ |
| | 213 | /* Creates a new barrier object and returns a handle to it. |
| | 214 | * The barrier has the specified size. |
| | 215 | * The new object will be allocated in the given scope. */ |
| | 216 | /*@ requires scope <= $root; |
| | 217 | @ requires size >= 0; |
| | 218 | @ $depends \nothing; |
| | 219 | @ $guards $true; |
| | 220 | @ assigns \nothing; |
| | 221 | @ */ |
| | 222 | $gbarrier $gbarrier_create($scope scope, int size); |
| | 223 | }}} |
| | 224 | |
| | 225 | {{{ |
| | 226 | /* Destroys the gbarrier */ |
| | 227 | /*@ requires barrier != \null; |
| | 228 | @ $guards $true; |
| | 229 | @ $depends \nothing; |
| | 230 | @ assigns barrier;//barrier has pointer type, and is converted into $memory type automatically |
| | 231 | @ */ |
| | 232 | void $gbarrier_destroy($gbarrier barrier); |
| | 233 | }}} |
| | 234 | |
| | 235 | {{{ |
| | 236 | /* checks if the global barrier has a vacancy at the specified place */ |
| | 237 | /*@ requires place >= 0; |
| | 238 | @*/ |
| | 239 | bool $gbarrier_vacant($gbarrier barrier, int place); |
| | 240 | }}} |
| | 241 | |
| | 242 | {{{ |
| | 243 | /* returns the process reference that takes the given place of the global barrier */ |
| | 244 | $proc $gbarrier_process_at($gbarrier barrier, int place); |
| | 245 | }}} |
| | 246 | |
| | 247 | {{{ |
| | 248 | /* Creates a new local barrier object and returns a handle to it. |
| | 249 | * The new barrier will be affiliated with the specified global |
| | 250 | * barrier. This local barrier handle will be used as an |
| | 251 | * argument in most barrier functions. The place must be in |
| | 252 | * [0,size-1] and specifies the place in the global barrier |
| | 253 | * that will be occupied by the local barrier. |
| | 254 | * Only one call to $barrier_create may occur for each barrier-place pair. |
| | 255 | * The new object will be allocated in the given scope. */ |
| | 256 | /*@ requires scope <= $root && gbarrier!=\null && place >= 0; |
| | 257 | *@ ensures $gbarrier_process_at(gbarrier, place)==$self; |
| | 258 | *@ $depends $calls($barrier_create, $everything, gbarrier, place); |
| | 259 | *@ assigns \nothing; |
| | 260 | *@ behavior success: |
| | 261 | *@ assumes $gbarrier_vacant(gbarrier, place); |
| | 262 | *@ allocates \result, scope; |
| | 263 | *@ behavior failure: |
| | 264 | *@ assumes !$gbarrier_vacant(gbarrier, place); |
| | 265 | *@ allocates \nothing, scope; |
| | 266 | *@ complete behaviors; |
| | 267 | *@ disjoint behaviors; |
| | 268 | */ |
| | 269 | $barrier $barrier_create($scope scope, $gbarrier gbarrier, int place); |
| | 270 | }}} |
| | 271 | |
| | 272 | {{{ |
| | 273 | /* Destroys the barrier. */ |
| | 274 | /*@ requires barrier != \null ==> \freeable{Here}(barrier); |
| | 275 | @ assigns \nothing; |
| | 276 | @ frees barrier; |
| | 277 | @ ensures barrier !=null ==> \allocable{Here}{barrier}; // what does it mean by \allocable? |
| | 278 | @ // the above is actually copied from ACSL reference where there is an example of contracts for free(). |
| | 279 | @ |
| | 280 | @*/ |
| | 281 | void $barrier_destroy($barrier barrier); |
| | 282 | }}} |
| | 283 | |
| | 284 | {{{ |
| | 285 | /* Calls the barrier associated with this local barrier object.*/ |
| | 286 | /*@ $depends \nothing; |
| | 287 | @ assigns \nothing; // although the barrier records is updated but it gets cleaned up when the method returns |
| | 288 | @*/ |
| | 289 | void $barrier_call($barrier barrier); |
| | 290 | }}} |