factor/extra/concurrency/locks/locks.factor

79 lines
2.1 KiB
Factor
Raw Normal View History

2008-02-18 06:07:40 -05:00
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2008-02-18 10:08:59 -05:00
USING: dlists kernel threads continuations math
concurrency.conditions ;
2008-02-18 06:07:40 -05:00
IN: concurrency.locks
! Simple critical sections
TUPLE: lock threads owner ;
: <lock> <dlist> lock construct-boa ;
<PRIVATE
2008-02-18 10:08:59 -05:00
: acquire-lock ( lock timeout -- )
over lock-owner
[ 2dup >r lock-threads r> wait ] when drop
2008-02-18 06:07:40 -05:00
self swap set-lock-owner ;
: release-lock ( lock -- )
f over set-lock-owner
lock-threads notify-1 ;
2008-02-18 10:08:59 -05:00
: do-lock ( lock timeout quot acquire release -- )
>r >r pick r> call over r> curry [ ] cleanup ; inline
2008-02-18 06:07:40 -05:00
PRIVATE>
2008-02-18 10:08:59 -05:00
: with-lock ( lock timeout quot -- )
2008-02-18 06:07:40 -05:00
[ acquire-lock ] [ release-lock ] do-lock ; inline
2008-02-18 10:08:59 -05:00
: with-reentrant-lock ( lock timeout quot -- )
2008-02-18 06:07:40 -05:00
over lock-owner self eq?
[ nip call ] [ with-lock ] if ; inline
! Many-reader/single-writer locks
TUPLE: rw-lock readers writers reader# writer ;
: <rw-lock> ( -- lock )
<dlist> <dlist> 0 f rw-lock construct-boa ;
<PRIVATE
2008-02-18 10:08:59 -05:00
: acquire-read-lock ( timeout lock -- )
dup rw-lock-writer
[ 2dup >r rw-lock-readers r> wait ] when drop
2008-02-18 06:07:40 -05:00
dup rw-lock-reader# 1+ swap set-rw-lock-reader# ;
: notify-writer ( lock -- )
2008-02-18 10:08:59 -05:00
rw-lock-writers notify-1 ;
2008-02-18 06:07:40 -05:00
: release-read-lock ( lock -- )
dup rw-lock-reader# 1- dup pick set-rw-lock-reader#
2008-02-18 10:08:59 -05:00
zero? [ notify-writer ] [ drop ] if ;
2008-02-18 06:07:40 -05:00
: acquire-write-lock ( lock -- )
dup rw-lock-writer over rw-lock-reader# 0 > or
2008-02-18 10:08:59 -05:00
[ 2dup >r rw-lock-writers r> wait ] when drop
self swap set-rw-lock-writer ;
2008-02-18 06:07:40 -05:00
: release-write-lock ( lock -- )
f over set-rw-lock-writer
dup rw-lock-readers dlist-empty?
[ notify-writer ] [ rw-lock-readers notify-all ] if ;
2008-02-18 10:08:59 -05:00
: do-recursive-rw-lock ( lock timeout quot quot' -- )
>r pick rw-lock-writer self eq? [ 2nip call ] r> if ; inline
2008-02-18 06:07:40 -05:00
PRIVATE>
2008-02-18 10:08:59 -05:00
: with-read-lock ( lock timeout quot -- )
2008-02-18 06:07:40 -05:00
[
[ acquire-read-lock ] [ release-read-lock ] do-lock
] do-recursive-rw-lock ; inline
2008-02-18 10:08:59 -05:00
: with-write-lock ( lock timeout quot -- )
2008-02-18 06:07:40 -05:00
[
[ acquire-write-lock ] [ release-write-lock ] do-lock
] do-recursive-rw-lock ; inline