| | 293 | |
| | 294 | * A simple C implementation of queue |
| | 295 | |
| | 296 | {{{ |
| | 297 | struct cqueue_t{ |
| | 298 | int data[]; |
| | 299 | $proc owner; |
| | 300 | }; |
| | 301 | }}} |
| | 302 | |
| | 303 | {{{ |
| | 304 | /*@ depends \noact; |
| | 305 | @ assigns \nothing; |
| | 306 | @ reads \nothing; |
| | 307 | @*/ |
| | 308 | $atomic_f void create(cqueue* q) |
| | 309 | { |
| | 310 | q = (cqueue*)$malloc($root, sizeof(cqueue)); |
| | 311 | q->owner=$proc_null; |
| | 312 | $seq_init(&q->data, 0, NULL); |
| | 313 | } |
| | 314 | }}} |
| | 315 | |
| | 316 | {{{ |
| | 317 | /*@ depends \read(q->owner)+\write(q->owner); |
| | 318 | @ assigns q->owner; |
| | 319 | */ |
| | 320 | $atomic_f _Bool lock(cqueue* q) |
| | 321 | $depends {$access(q->owner)} |
| | 322 | $assigns {q->owner} |
| | 323 | { |
| | 324 | if(q->owner==$self) |
| | 325 | return $true; |
| | 326 | if(q->owner == $proc_null){ |
| | 327 | q->owner=$self; |
| | 328 | return $true; |
| | 329 | }else |
| | 330 | return $false; |
| | 331 | } |
| | 332 | }}} |
| | 333 | |
| | 334 | {{{ |
| | 335 | /*@ depends \calls(enqueue, q, ...)+$calls(dequeue,q, ...); |
| | 336 | @ reads q->data; |
| | 337 | @ assigns \nothing; |
| | 338 | @*/ |
| | 339 | $pure $atomic_f int size(cqueue* q) |
| | 340 | { |
| | 341 | return $seq_length(&q->data); |
| | 342 | } |
| | 343 | }}} |
| | 344 | |
| | 345 | {{{ |
| | 346 | /*@ reads q->owner; |
| | 347 | @ behavior success: |
| | 348 | @ assumes q->owner==$self; |
| | 349 | @ $depends $access(q->owner); |
| | 350 | @ assigns q->owner; |
| | 351 | @ behavior failure: |
| | 352 | @ assumes q->owner!=$self; |
| | 353 | @ $depends \nothing; |
| | 354 | @ assigns \nothing; |
| | 355 | @*/ |
| | 356 | $atomic_f _Bool unlock(cqueue* q) |
| | 357 | { |
| | 358 | if(q->owner==$self) |
| | 359 | { |
| | 360 | q->owner=$proc_null; |
| | 361 | return $true; |
| | 362 | } |
| | 363 | return $false; |
| | 364 | } |
| | 365 | }}} |
| | 366 | |
| | 367 | {{{ |
| | 368 | /*@ depends calls(enqueue,q, ...); |
| | 369 | @ assigns q->data; |
| | 370 | @*/ |
| | 371 | $atomic_f _Bool enqueue(cqueue* q, int v) |
| | 372 | { |
| | 373 | $seq_append(&q->data, &v, 1); |
| | 374 | } |
| | 375 | }}} |
| | 376 | |
| | 377 | {{{ |
| | 378 | /*@ depends calls(enqueue, q, ...); |
| | 379 | @ assigns q->data; |
| | 380 | @*/ |
| | 381 | $atomic_f _Bool dequeue(cqueue* q, int* res) |
| | 382 | { |
| | 383 | $seq_remove(&q->data, $seq_length(&q->data)-1, res, 1); |
| | 384 | } |
| | 385 | }}} |