ck_pring
David Joseph 12 years ago
commit 36a2ba143a

3
.gitignore vendored

@ -139,3 +139,6 @@ regressions/ck_brlock/benchmark/throughput
regressions/ck_rwlock/benchmark/throughput
regressions/ck_queue/validate/ck_list
regressions/ck_queue/validate/ck_slist
regressions/ck_cohort/validate/validate
regressions/ck_cohort/benchmark/ck_cohort.LATENCY
regressions/ck_cohort/benchmark/ck_cohort.THROUGHPUT

2
configure vendored

@ -33,7 +33,7 @@ EXIT_FAILURE=1
P_PWD=`pwd`
MAINTAINER='sbahra@repnop.org'
VERSION=${VERSION:-'0.2.15'}
VERSION=${VERSION:-'0.2.17'}
VERSION_MAJOR='0'
BUILD="$PWD/build/ck.build"
PREFIX=${PREFIX:-"/usr/local"}

@ -0,0 +1,65 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd February 24, 2013.
.Dt CK_COHORT_INIT 3
.Sh NAME
.Nm CK_COHORT_INIT
.Nd initialize instance of a cohort type
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_INIT "COHORT_NAME cohort_name" "COHORT *cohort" "void *global_lock" \
"void *local_lock" "unsigned int pass_limit"
.Sh DESCRIPTION
Until a cohort instance is initialized using the CK_COHORT_INIT macro, any operations
involving it will have undefined behavior. After this macro has been called, the cohort
pointed to by the
.Fa cohort
argument will use the lock pointed to by
.Fa global_lock
as its global lock and the lock pointed to by
.Fa local_lock
as its local lock.
.Pp
The cohort will relinquish its global lock after
.Fa pass_limit
consecutive acquisitions of its local lock, even if there are other threads waiting.
If you are unsure of a value to use for the
.Fa pass_limit
argument, you should use CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT.
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_LOCK 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Xr CK_COHORT_TRYLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,58 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd February 24, 2013.
.Dt CK_COHORT_INSTANCE 3
.Sh NAME
.Nm CK_COHORT_INSTANCE
.Nd declare an instance of a cohort type
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_INSTANCE "COHORT_NAME cohort_name"
.Sh DESCRIPTION
The user must use this macro to declare instances of cohort types that they have
defined. For instance, if they have used the CK_COHORT_PROTOTYPE macro to define
a cohort type with name foo, they would create an instance of this type as follows:
.br
CK_COHORT_INSTANCE(foo) cohort;
.Pp
This macro should also be used when allocating memory for cohorts. For instance,
to allocate a block of 4 cohorts:
.br
CK_COHORT_INSTANCE(foo) *cohorts = malloc(4 * sizeof(CK_COHORT_INSTANCE(foo)));
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_LOCK 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Xr CK_COHORT_TRYLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,60 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd February 24, 2013.
.Dt CK_COHORT_LOCK 3
.Sh NAME
.Nm CK_COHORT_LOCK
.Nd acquire cohort lock
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_LOCK "COHORT_NAME cohort_name" "COHORT *cohort" "void *global_context" \
"void *local_context"
.Sh DESCRIPTION
This call attempts to acquire both the local and global (if necessary) locks from
.Fa cohort .
The call will block until both locks have been acquired.
.Fa global_context
will be passed as the second argument to the function that was provided as the
.Fa global_lock_method
argument to CK_COHORT_PROTOTYPE if that method is called, and
.Fa local_context
will be passed to the function specified by
.Fa local_lock_method
.
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_INIT 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Xr CK_COHORT_TRYLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,74 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd February 24, 2013.
.Dt CK_COHORT_PROTOTYPE 3
.Sh NAME
.Nm CK_COHORT_PROTOTYPE
.Nd define cohort type with specified lock types
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_PROTOTYPE "COHORT_NAME cohort_name" "TYPE global_lock_method" \
"LOCK_FXN global_unlock_method" "LOCK_FXN local_lock_method" "LOCK_FXN local_unlock_method"
.Sh DESCRIPTION
The ck_cohort.h header file does not define any cohort types. Instead, the user must use
the CK_COHORT_PROTOTYPE or
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3
macros to define any types they want to use. They must use CK_COHORT_TRYLOCK_PROTOTYPE
if they want their cohort type to support trylock operations.
The CK_COHORT_PROTOTYPE macro takes the following arguments:
.Pp
.Fa cohort_name
: An identifier used for this cohort type. This will have to be passed to each
of the other CK_COHORT macros.
.br
.Fa global_lock_method
: The method that should be called to acquire the global lock
.br
.Fa global_unlock_method
: The method that should be called to relinquish the global lock
.br
.Fa local_lock_method
: The method that should be called to acquire the local lock
.br
.Fa local_unlock_method
: The method that should be called to relinquish the local lock
.Pp
Instances of the defined cohort type can be declared as:
.br
CK_COHORT_INSTANCE(cohort_name) cohort;
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_INIT 3 ,
.Xr CK_COHORT_LOCK 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,67 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd March 9, 2013.
.Dt CK_COHORT_TRYLOCK 3
.Sh NAME
.Nm CK_COHORT_TRYLOCK
.Nd try to acquire cohort lock
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_TRYLOCK "COHORT_NAME cohort_name" "COHORT *cohort" "void *global_trylock_context" \
"void *local_trylock_context" "void *lock_unlock_context"
.Sh DESCRIPTION
This call attempts to acquire both the local and global (if necessary) locks from
.Fa cohort .
It can only be used with cohort types that were defined using the
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3
macro. The call will not block and will return a bool that will evaluate to true iff
the cohort was successfully acquired.
.Fa global_trylock_context
will be passed as the second argument to the function that was provided as the
.Fa global_trylock_method
argument to CK_COHORT_TRYLOCK_PROTOTYPE if that method is called, and
.Fa local_trylock_context
will be passed to the function specified by
.Fa local_trylock_method .
If the global lock acquisition fails, then the cohort will immediately release its
local lock as well, and
.Fa local_unlock_context
will be passed to the function specified by
.Fa local_unlock_method
when this call is made.
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_INIT 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,82 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd March 9, 2013.
.Dt CK_COHORT_TRYLOCK_PROTOTYPE 3
.Sh NAME
.Nm CK_COHORT_TRYLOCK_PROTOTYPE
.Nd define cohort type with specified lock types
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_TRYLOCK_PROTOTYPE "COHORT_NAME cohort_name" "LOCK_FXN global_lock_method" \
"LOCK_FXN global_unlock_method" "TRYLOCK_FXN global_trylock_method" \
"LOCK_FXN local_lock_method" "LOCK_FXN local_unlock_method" "TRYLOCK_FXN local_trylock_method"
.Sh DESCRIPTION
The ck_cohort.h header file does not define any cohort types. Instead, the user must use
the CK_COHORT_PROTOTYPE or CK_COHORT_TRYLOCK_PROTOTYPE macros to define any types
they want to use.
They must use CK_COHORT_TRYLOCK_PROTOTYPE if they want their cohort type to have support
for trylock operations. The CK_COHORT_TRYLOCK_PROTOTYPE macro takes the following arguments:
.Pp
.Fa cohort_name
: An identifier used for this cohort type. This will have to be passed to each
of the other CK_COHORT macros.
.br
.Fa global_lock_method
: The method that should be called to acquire the global lock
.br
.Fa global_unlock_method
: The method that should be called to relinquish the global lock
.br
.Fa global_trylock_method
: The method that should be called to try to acquire the global lock.
It should not block and return true iff the lock was successfully acquired.
.br
.Fa local_lock_method
: The method that should be called to acquire the local lock
.br
.Fa local_unlock_method
: The method that should be called to relinquish the local lock
.br
.Fa local_trylock_method
: The method that should be called to try to acquire the local lock.
It should not block and return true iff the lock was successfully acquired.
.Pp
Instances of the defined cohort type can be declared as:
.br
CK_COHORT_INSTANCE(cohort_name) cohort;
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_INIT 3 ,
.Xr CK_COHORT_LOCK 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,60 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd February 24, 2013.
.Dt CK_COHORT_UNLOCK 3
.Sh NAME
.Nm CK_COHORT_UNLOCK
.Nd release cohort lock
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_UNLOCK "COHORT_NAME cohort_name" "COHORT *cohort" "void *global_context" \
"void *local_context"
.Sh DESCRIPTION
This call instructs
.Fa cohort
to relinquish its local lock and potentially its global lock as well.
.Fa global_context
will be passed as the second argument to the function that was provided as the
.Fa global_lock_method
argument to CK_COHORT_PROTOTYPE if that method is called, and
.Fa local_context
will be passed to the function specified by
.Fa local_lock_method
.
.Sh SEE ALSO
.Xr ck_cohort 3 ,
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_INIT 3 ,
.Xr CK_COHORT_LOCK 3 ,
.Xr CK_COHORT_TRYLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -5,6 +5,7 @@ GZIP=@GZIP@
GZIP_SUFFIX=.3@GZIP_SUFFIX@
BUILD_DIR=@BUILD_DIR@
SRC_DIR=@SRC_DIR@
HTML_SUFFIX=.html
OBJECTS=ck_ht_count \
ck_ht_destroy \
@ -75,13 +76,35 @@ OBJECTS=ck_ht_count \
ck_hs_grow \
ck_hs_count \
ck_hs_reset \
ck_hs_stat
ck_hs_stat \
ck_cohort \
CK_COHORT_PROTOTYPE \
CK_COHORT_TRYLOCK_PROTOTYPE \
CK_COHORT_INSTANCE \
CK_COHORT_INIT \
CK_COHORT_LOCK \
CK_COHORT_UNLOCK \
CK_COHORT_TRYLOCK \
ck_pr \
ck_pr_barrier \
ck_pr_fas \
ck_pr_fence_load \
ck_pr_fence_load_depends \
ck_pr_fence_memory \
ck_pr_fence_store \
ck_pr_stall
all:
for target in $(OBJECTS); do \
$(GZIP) $(SRC_DIR)/doc/$$target > $(BUILD_DIR)/doc/$$target$(GZIP_SUFFIX); \
done
html:
for target in $(OBJECTS); do \
echo $$target; \
groff -man -Tascii $(SRC_DIR)/doc/$$target | man2html -noheads -bare -compress -cgiurl='$$title.html' > $(BUILD_DIR)/doc/$$target$(HTML_SUFFIX); \
done
install:
mkdir -p $(DESTDIR)/$(MANDIR)/man3 || exit
cp *$(GZIP_SUFFIX) $(DESTDIR)/$(MANDIR)/man3 || exit
@ -92,5 +115,5 @@ uninstall:
done
clean:
rm -f $(BUILD_DIR)/doc/*~ $(BUILD_DIR)/doc/*.3.gz
rm -f $(BUILD_DIR)/doc/*~ $(BUILD_DIR)/doc/*.3.gz $(BUILD_DIR)/doc/*.html

@ -29,7 +29,7 @@
.Dt CK_BAG_SET_SPMC 3
.Sh NAME
.Nm ck_bag_set_spmc
.Nd Replace the first occurence of a value in a bag. Insert value into the bag if value didn't previously exist.
.Nd replace the first occurence of a value in a bag
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS

@ -0,0 +1,202 @@
.\"
.\" Copyright 2013 Brendon Scheinman.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd February 24, 2013.
.Dt ck_cohort 3
.Sh NAME
.Nm ck_cohort
.Nd generalized interface for lock cohorts
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_cohort.h
.Fn CK_COHORT_PROTOTYPE "COHORT_NAME cohort_name" "LOCK_FXN global_lock_method" \
"LOCK_FXN global_unlock_method" "LOCK_FXN local_lock_method" "LOCK_FXN local_unlock_method"
.Fn CK_COHORT_TRYLOCK_PROTOTYPE "COHORT_NAME cohort_name" \
"LOCK_FXN global_lock_method" "LOCK_FXN global_unlock_method" "TRYLOCK_FXN global_trylock_method" \
"LOCK_FXN local_lock_method" "LOCK_FXN local_unlock_method" "TRYLOCK_FXN local_trylock_method"
.Fn CK_COHORT_INSTANCE "COHORT_NAME cohort_name"
.Fn CK_COHORT_INIT "COHORT_NAME cohort_name" "ck_cohort *cohort" \
"void *global_lock" "void *local_lock" "unsigned int pass_limit"
.Fn CK_COHORT_LOCK "COHORT_NAME cohort_name" "ck_cohort *cohort" \
"void *global_context" "void *local_context"
.Fn CK_COHORT_UNLOCK "COHORT_NAME cohort_name" "ck_cohort *cohort" \
"void *global_context" "void *local_context"
.Pp
Where LOCK_FXN refers to a method with the signature
.br
void(void *lock, void *context)
.br
and TRYLOCK_FXN refers to a method with the signature
.br
bool(void *lock, void *context)
.Pp
The
.Fa context
argument in each signature is used to pass along any additional information that
the lock might need for its lock, unlock and trylock methods. The values for this
argument are provided to each call to
.Xr CK_COHORT_LOCK 3
,
.Xr CK_COHORT_UNLOCK 3
and
.Xr CK_COHORT_TRYLOCK 3
.
.Sh DESCRIPTION
ck_cohort.h provides an interface for defining lock cohorts with
arbitrary lock types. Cohorts are a mechanism for coordinating
threads on NUMA architectures in order to reduce the frequency
with which a lock is passed between threads on different clusters.
.Pp
Before using a cohort, the user must define a cohort type using
either the
.Fn CK_COHORT_PROTOTYPE
or the
.Fn CK_COHORT_TRYLOCK_PROTOTYPE
macros. These macros allow the user to specify the lock methods that
they would like the cohort to use. See the
.Xr CK_COHORT_PROTOTYPE 3
and
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3
man pages for more details.
.Pp
.Sh EXAMPLE
.Bd -literal -offset indent
#include <stdlib.h>
#include <pthread.h>
#include <ck_pr.h>
#include <ck_cohort.h>
#include <ck_spinlock.h>
/*
* Create lock/unlock methods with signatures that match
* the required signature
*/
static void
ck_spinlock_lock_with_context(ck_spinlock_t *lock, void *context)
{
(void)context;
ck_spinlock_lock(lock);
return;
}
static void
ck_spinlock_unlock_with_context(ck_spinlock_t *lock, void *context)
{
(void)context;
ck_spinlock_unlock(lock);
return;
}
/*
* define a cohort type named "test_cohort" that will use
* the above methods for both its global and local locks
*/
CK_COHORT_PROTOTYPE(test_cohort,
ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context,
ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context)
static ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;
static unsigned int ready;
static void*
function(void *context)
{
CK_COHORT_INSTANCE(test_cohort) *cohort = context;
while (ready == 0);
while (ready > 0) {
/*
* acquire the cohort lock before performing critical section.
* note that we pass NULL for both the global and local context
* arguments because neither the lock nor unlock functions
* will use them.
*/
CK_COHORT_LOCK(test_cohort, cohort, NULL, NULL);
/* perform critical section */
/* relinquish cohort lock */
CK_COHORT_UNLOCK(test_cohort, cohort, NULL, NULL);
}
return NULL;
}
int
main(void)
{
unsigned int nthr = 4;
unsigned int n_cohorts = 2;
unsigned int i;
/* allocate 2 cohorts of the defined type */
CK_COHORT_INSTANCE(test_cohort) *cohorts =
calloc(n_cohorts, sizeof(CK_COHORT_INSTANCE(test_cohort)));
/* create local locks to use with each cohort */
ck_spinlock_t *local_locks =
calloc(n_cohorts, sizeof(ck_spinlock_t));
pthread_t *threads =
calloc(nthr, sizeof(pthread_t));
/* initialize each of the cohorts before using them */
for (i = 0 ; i < n_cohorts ; ++i) {
CK_COHORT_INIT(test_cohort, cohorts + i, &global_lock, local_locks + i,
CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);
}
/* start each thread and assign cohorts equally */
for (i = 0 ; i < nthr ; ++i) {
pthread_create(threads + i, NULL, function, cohorts + (i % n_cohorts));
}
ck_pr_store_uint(&ready, 1);
sleep(10);
ck_pr_store_uint(&ready, 0);
for (i = 0 ; i < nthr ; ++i) {
pthread_join(threads[i], NULL);
}
return 0;
}
.Ed
.Sh SEE ALSO
.Xr CK_COHORT_PROTOTYPE 3 ,
.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,
.Xr CK_COHORT_INSTANCE 3 ,
.Xr CK_COHORT_INITIALIZER 3 ,
.Xr CK_COHORT_INIT 3 ,
.Xr CK_COHORT_LOCK 3 ,
.Xr CK_COHORT_UNLOCK 3 ,
.Xr CK_COHORT_TRYLOCK 3 ,
.Pp
Additional information available at http://concurrencykit.org/

@ -95,6 +95,7 @@ function(void)
free(s);
return;
}
.Ed
.Sh RETURN VALUES
This function has no return value.
.Sh ERRORS

@ -33,9 +33,7 @@
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_epoch.h
typedef struct ck_epoch_entry ck_epoch_entry_t;
typedef void ck_epoch_cb_t(ck_epoch_entry_t *);
.Ft void
.Fn ck_epoch_call "ck_epoch_t *epoch" "ck_epoch_record_t *record" "ck_epoch_entry_t *entry" "ck_epoch_cb_t *function"
@ -114,6 +112,7 @@ function(void)
ck_epoch_poll(&epoch, record);
return;
}
.Ed
.Sh RETURN VALUES
This function has no return value.
.Sh ERRORS

@ -99,6 +99,7 @@ function(void)
free(s);
return;
}
.Ed
.Sh RETURN VALUES
This function has no return value.
.Sh ERRORS

@ -28,7 +28,7 @@
.Dt CK_HS_DESTROY 3
.Sh NAME
.Nm ck_hs_destroy
.Nd initialize a hash set
.Nd destroy hash set
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
@ -43,7 +43,6 @@ function will request that the underlying allocator, as specified by the
function, immediately destroy the object pointed to by the
.Fa hs
argument.
The user must guarantee that no threads are accessing the object pointed to
by
.Fa hs

@ -48,6 +48,7 @@ struct ck_hs_stat {
unsigned long n_entries; /* Current number of keys in hash set. */
unsigned int probe_maximum; /* Longest read-side probe sequence. */
};
.Ed
.Sh RETURN VALUES
.Fn ck_hs_stat 3
has no return value.

@ -47,6 +47,7 @@ struct ck_ht_stat {
uint64_t probe_maximum; /* Longest read-side probe sequence. */
uint64_t n_entries; /* Current number of keys in hash set. */
};
.Ed
.Sh RETURN VALUES
.Fn ck_ht_stat 3
has no return value.

@ -0,0 +1,69 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr 3
.Sh NAME
.Nm ck_pr
.Nd concurrency primitives interface
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Sh DESCRIPTION
ck_pr.h provides an interface to volatile atomic instructions,
memory barriers and busy-wait facilities as provided by the
underlying processor. The presence of an atomic operation
is detected by the presence of a corresponding CK_F_PR macro.
For example, the availability of
.Xr ck_pr_add_16 3
would be determined by the presence of CK_F_PR_ADD_16.
.Sh SEE ALSO
.Xr ck_pr_stall 3 ,
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_barrier 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,66 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_barrier 3
.Sh NAME
.Nm ck_pr_barrier
.Nd compiler optimization barrier
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void
.Fn ck_pr_barrier void
.Sh DESCRIPTION
The
.Fn ck_pr_barrier 3
function is used to disable code movement optimizations
across the invocation of the function.
.Sh SEE ALSO
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,90 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_fas 3
.Sh NAME
.Nm ck_pr_fas
.Nd atomic swap operation
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void *
.Fn ck_pr_fas_ptr "void *target" "void *new_value"
.Ft double
.Fn ck_pr_fas_double "double *target" "double new_value"
.Ft char
.Fn ck_pr_fas_char "char *target" "char new_value"
.Ft unsigned int
.Fn ck_pr_fas_uint "unsigned int *target" "unsigned int new_value"
.Ft int
.Fn ck_pr_fas_int "int *target" "int new_value"
.Ft uint64_t
.Fn ck_pr_fas_64 "uint64_t *target" "uint64_t new_value"
.Ft uint32_t
.Fn ck_pr_fas_32 "uint32_t *target" "uint32_t new_value"
.Ft uint16_t
.Fn ck_pr_fas_16 "uint16_t *target" "uint16_t new_value"
.Ft uint8_t
.Fn ck_pr_fas_8 "uint8_t *target" "uint8_t new_value"
.Sh DESCRIPTION
The
.Fn ck_pr_fas 3
function will atomically fetch the value pointed to
by
.Fa target
and then replace it with the value specified by
.Fa new_value .
.Sh RETURN VALUES
This function will return the value pointed to by
.Fa target
at the time of operation invocation before it was
atomically replaced with
.Fa new_value .
.Sh SEE ALSO
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,108 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_fence_load 3
.Sh NAME
.Nm ck_pr_fence_load
.Nd enforce partial ordering of load operations
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void
.Fn ck_pr_fence_load void
.Ft void
.Fn ck_pr_fence_strict_load void
.Sh DESCRIPTION
This function will enforce the ordering of any memory load
and
.Fn ck_pr_load 3
operations relative to the invocation of the function. Any
store operations that were committed on remote processors
and received by the calling processor before the invocation of
.Fn ck_pr_fence_load
will also be made visible only after a call to
.Fn ck_pr_fence_load .
This function will always serve as an implicit compiler barrier.
On architectures with CK_MD_TSO or CK_MD_PSO specified (total store ordering
and partial store ordering respectively), this operation will only serve
as a compiler barrier and no fence instructions will be emitted. To
force the unconditional emission of a load fence, use
.Fn ck_pr_fence_strict_load .
Architectures implementing CK_MD_RMO will always emit a load fence.
.Sh EXAMPLE
.Bd -literal -offset indent
#include <ck_pr.h>
static unsigned int a;
static unsigned int b;
void
function(void)
{
unsigned int snapshot_a, snapshot_b;
snapshot_a = ck_pr_load_uint(&a);
/*
* Guarantee that the load from "a" completes
* before the load from "b".
*/
ck_pr_fence_load();
snapshot_b = ck_pr_load_uint(&b);
return;
}
.Ed
.Sh RETURN VALUES
This function has no return value.
.Sh SEE ALSO
.Xr ck_pr_stall 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_barrier 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,70 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_fence_load_depends 3
.Sh NAME
.Nm ck_pr_fence_load_depends
.Nd data dependency barrier
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void
.Fn ck_pr_fence_load_depends void
.Sh DESCRIPTION
The
.Fn ck_pr_fence_load_depends 3
emits necessary fences for pure data-dependent loads. It currently only serves as a compiler
barrier for Concurrency Kit's supported platforms. Unless you're on architecture
which re-orders data-dependent loads (such as the defunct Alpha), this function is unnecessary.
.Sh RETURN VALUES
This function has no return value.
.Sh SEE ALSO
.Xr ck_pr_stall 3 ,
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_barrier 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,111 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_fence_memory 3
.Sh NAME
.Nm ck_pr_fence_memory
.Nd enforce partial ordering of all memory operations
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void
.Fn ck_pr_fence_memory
.Ft void
.Fn ck_pr_fence_strict_memory
.Sh DESCRIPTION
The
.Fn ck_pr_fence_memory 3
function will enforce the ordering of any memory operations
with respect to the invocation of the function. This function
will always serve as an implicit compiler barrier.
Achitectures implementing CK_MD_TSO will
only have this function serve as a compiler barrier and
no fence instructions will be emitted. Architectures
implementing CK_MD_PSO and CK_MD_RMO will always emit
an instructions which provides the specified ordering
guarantees. To force the unconditional emission of a memory
fence, use
.Fn ck_pr_fence_strict_memory .
.Sh EXAMPLE
.Bd -literal -offset indent
#include <ck_pr.h>
static int a = 0;
static int b;
static int c;
static int d;
void
function(void)
{
int snapshot_a;
ck_pr_store_int(&b, 1);
snapshot_a = ck_pr_load_int(&a);
/*
* Make sure previous memory operations are
* ordered with respect to memory operations
* following the ck_pr_fence_memory.
*/
ck_pr_fence_memory();
ck_pr_store_int(&d, 3);
ck_pr_store_int(&c, 2);
return;
}
.Ed
.Sh RETURN VALUES
This function has no return value.
.Sh SEE ALSO
.Xr ck_pr_stall 3 ,
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_barrier 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,107 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_fence_store 3
.Sh NAME
.Nm ck_pr_fence_store
.Nd enforce partial ordering of store operations
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void
.Fn ck_pr_fence_store void
.Ft void
.Fn ck_pr_fence_strict_store void
.Sh DESCRIPTION
The
.Fn ck_pr_fence_store
function will enfore the ordering of any memory store,
.Fn ck_pr_store
and atomic read-modify-write operations relative to
the invocation of the function. This function will
always serve as an implicit compiler barrier. On
architectures implementing CK_MD_TSO, this operation
will only serve as a compiler barrier and no fences
will be emitted. On architectures implementing
CK_MD_PSO and CK_MD_RMO, a store fence will be
emitted. To force the unconditional emission of
a store fence, use
.Fn ck_pr_fence_strict_store .
.Sh EXAMPLE
.Bd -literal -offset indent
#include <ck_pr.h>
static int a = 0;
static int b = 0;
static int c = 0;
void
function(void)
{
ck_pr_store_int(&a, 1);
/*
* Guarantee that the store to a is completed
* with respect to the stores of b and c.
*/
ck_pr_fence_store();
ck_pr_store_int(&b, 2);
ck_pr_store_int(&c, 2);
return;
}
.Ed
.Sh RETURN VALUES
This function has no return value.
.Sh SEE ALSO
.Xr ck_pr_stall 3 ,
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_barrier 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -0,0 +1,86 @@
.\"
.\" Copyright 2013 Samy Al Bahra.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"
.Dd April 7, 2013
.Dt ck_pr_stall 3
.Sh NAME
.Nm ck_pr_stall
.Nd busy-wait primitive
.Sh LIBRARY
Concurrency Kit (libck, \-lck)
.Sh SYNOPSIS
.In ck_pr.h
.Ft void
.Fn ck_pr_stall void
.Sh DESCRIPTION
The
.Fn ck_pr_stall 3
function should be used inside retry paths of busy-wait loops.
It not only serves as a compiler barrier, but on some architectures
it emits cycle-saving instructions.
.Sh EXAMPLE
.Bd -literal -offset indent
#include <ck_pr.h>
static int ready = 0;
void
function(void)
{
/* Busy-wait until ready is non-zero. */
while (ck_pr_load_int(&ready) == 0)
ck_pr_stall();
return;
}
.Ed
.Sh SEE ALSO
.Xr ck_pr_fence_load 3 ,
.Xr ck_pr_fence_load_depends 3 ,
.Xr ck_pr_fence_store 3 ,
.Xr ck_pr_fence_memory 3 ,
.Xr ck_pr_barrier 3 ,
.Xr ck_pr_fas 3 ,
.Xr ck_pr_load 3 ,
.Xr ck_pr_store 3 ,
.Xr ck_pr_faa 3 ,
.Xr ck_pr_inc 3 ,
.Xr ck_pr_dec 3 ,
.Xr ck_pr_neg 3 ,
.Xr ck_pr_not 3 ,
.Xr ck_pr_add 3 ,
.Xr ck_pr_sub 3 ,
.Xr ck_pr_and 3 ,
.Xr ck_pr_or 3 ,
.Xr ck_pr_xor 3 ,
.Xr ck_pr_cas 3 ,
.Xr ck_pr_btc 3 ,
.Xr ck_pr_bts 3 ,
.Xr ck_pr_btr 3
.Pp
Additional information available at http://concurrencykit.org/

@ -50,11 +50,12 @@ enum ck_cohort_state {
#define CK_COHORT_INIT(N, C, GL, LL, P) ck_cohort_##N##_init(C, GL, LL, P)
#define CK_COHORT_LOCK(N, C, GC, LC) ck_cohort_##N##_lock(C, GC, LC)
#define CK_COHORT_UNLOCK(N, C, GC, LC) ck_cohort_##N##_unlock(C, GC, LC)
#define CK_COHORT_TRYLOCK(N, C, GLC, LLC, LUC) ck_cohort_##N##_trylock(C, GLC, LLC, LUC)
#define CK_COHORT_PROTOTYPE(N, GT, GL, GU, LT, LL, LU) \
#define CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \
CK_COHORT_INSTANCE(N) { \
GT *global_lock; \
LT *local_lock; \
void *global_lock; \
void *local_lock; \
enum ck_cohort_state release_state; \
unsigned int waiting_threads; \
unsigned int acquire_count; \
@ -63,7 +64,7 @@ enum ck_cohort_state {
\
CK_CC_INLINE static void \
ck_cohort_##N##_init(struct ck_cohort_##N *cohort, \
GT *global_lock, LT *local_lock, unsigned int pass_limit) \
void *global_lock, void *local_lock, unsigned int pass_limit) \
{ \
cohort->global_lock = global_lock; \
cohort->local_lock = local_lock; \
@ -112,6 +113,33 @@ enum ck_cohort_state {
return; \
}
#define CK_COHORT_TRYLOCK_PROTOTYPE(N, GL, GU, GTL, LL, LU, LTL) \
CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \
CK_CC_INLINE static bool \
ck_cohort_##N##_trylock(CK_COHORT_INSTANCE(N) *cohort, \
void *global_context, void *local_context, \
void *local_unlock_context) \
{ \
\
bool trylock_result; \
\
ck_pr_inc_uint(&cohort->waiting_threads); \
trylock_result = LTL(cohort->local_lock, local_context); \
ck_pr_dec_uint(&cohort->waiting_threads); \
if (trylock_result == false) { \
return false; \
} \
\
if (cohort->release_state == CK_COHORT_STATE_GLOBAL && \
GTL(cohort->global_lock, global_context) == false) { \
LU(cohort->local_lock, local_unlock_context); \
return false; \
} \
\
++cohort->acquire_count; \
return true; \
}
#define CK_COHORT_INITIALIZER { \
.global_lock = NULL, \
.local_lock = NULL, \
@ -121,6 +149,5 @@ enum ck_cohort_state {
.local_pass_limit = CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT \
}
#endif /* _CK_COHORT_H */

@ -139,13 +139,13 @@ ck_fifo_spsc_dequeue(struct ck_fifo_spsc *fifo, void *value)
*/
entry = ck_pr_load_ptr(&fifo->head->next);
if (entry == NULL)
return (false);
return false;
/* If entry is visible, guarantee store to value is visible. */
ck_pr_store_ptr(value, entry->value);
ck_pr_fence_store();
ck_pr_store_ptr(&fifo->head, entry);
return (true);
return true;
}
/*
@ -165,14 +165,14 @@ ck_fifo_spsc_recycle(struct ck_fifo_spsc *fifo)
garbage = fifo->garbage;
fifo->garbage = garbage->next;
return (garbage);
return garbage;
}
CK_CC_INLINE static bool
ck_fifo_spsc_isempty(struct ck_fifo_spsc *fifo)
{
struct ck_fifo_spsc_entry *head = ck_pr_load_ptr(&fifo->head);
return (ck_pr_load_ptr(&head->next) == NULL);
return ck_pr_load_ptr(&head->next) == NULL;
}
#define CK_FIFO_SPSC_ISEMPTY(f) ((f)->head->next == NULL)
@ -355,12 +355,20 @@ ck_fifo_mpmc_dequeue(struct ck_fifo_mpmc *fifo,
* queue is empty.
*/
if (next.pointer == NULL)
return (false);
return false;
/* Forward the tail pointer if necessary. */
update.generation = tail.generation + 1;
ck_pr_cas_ptr_2(&fifo->tail, &tail, &update);
} else {
/*
* It is possible for head snapshot to have been
* re-used. Avoid deferencing during enqueue
* re-use.
*/
if (next.pointer == NULL)
continue;
/* Save value before commit. */
*(void **)value = ck_pr_load_ptr(&next.pointer->value);
@ -372,7 +380,7 @@ ck_fifo_mpmc_dequeue(struct ck_fifo_mpmc *fifo,
}
*garbage = head.pointer;
return (true);
return true;
}
CK_CC_INLINE static bool
@ -408,6 +416,13 @@ ck_fifo_mpmc_trydequeue(struct ck_fifo_mpmc *fifo,
ck_pr_cas_ptr_2(&fifo->tail, &tail, &update);
return false;
} else {
/*
* It is possible for head snapshot to have been
* re-used. Avoid deferencing during enqueue.
*/
if (next.pointer == NULL)
return false;
/* Save value before commit. */
*(void **)value = ck_pr_load_ptr(&next.pointer->value);

@ -88,7 +88,8 @@ typedef struct ck_hs_iterator ck_hs_iterator_t;
void ck_hs_iterator_init(ck_hs_iterator_t *);
bool ck_hs_next(ck_hs_t *, ck_hs_iterator_t *, void **);
bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *, ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long);
bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *,
ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long);
void ck_hs_destroy(ck_hs_t *);
void *ck_hs_get(ck_hs_t *, unsigned long, const void *);
bool ck_hs_put(ck_hs_t *, unsigned long, const void *);
@ -100,3 +101,4 @@ bool ck_hs_reset(ck_hs_t *);
void ck_hs_stat(ck_hs_t *, struct ck_hs_stat *);
#endif /* _CK_HS_H */

@ -29,8 +29,8 @@
#define _CK_PFLOCK_H
/*
* This is a naive implementation of phase-fair locks derived
* from the work described in:
* This is an implementation of phase-fair locks derived from the work
* described in:
* Brandenburg, B. and Anderson, J. 2010. Spin-Based
* Reader-Writer Synchronization for Multiprocessor Real-Time Systems
*/

@ -75,6 +75,27 @@
return ring->size; \
} \
CK_CC_INLINE static bool \
ck_ring_enqueue_spsc_size_##name(struct ck_ring_##name *ring, \
struct type *entry, \
unsigned int *size) \
{ \
unsigned int consumer, producer, delta; \
unsigned int mask = ring->mask; \
\
consumer = ck_pr_load_uint(&ring->c_head); \
producer = ring->p_tail; \
delta = producer + 1; \
*size = (producer - consumer) & mask; \
\
if ((delta & mask) == (consumer & mask)) \
return false; \
\
ring->ring[producer & mask] = *entry; \
ck_pr_fence_store(); \
ck_pr_store_uint(&ring->p_tail, delta); \
return true; \
} \
CK_CC_INLINE static bool \
ck_ring_enqueue_spsc_##name(struct ck_ring_##name *ring, \
struct type *entry) \
{ \
@ -114,6 +135,13 @@
return true; \
} \
CK_CC_INLINE static bool \
ck_ring_enqueue_spmc_size_##name(struct ck_ring_##name *ring, \
void *entry, unsigned int *size) \
{ \
\
return ck_ring_enqueue_spsc_size_##name(ring, entry, size); \
} \
CK_CC_INLINE static bool \
ck_ring_enqueue_spmc_##name(struct ck_ring_##name *ring, void *entry) \
{ \
\
@ -167,23 +195,27 @@
}
#define CK_RING_INSTANCE(name) \
#define CK_RING_INSTANCE(name) \
struct ck_ring_##name
#define CK_RING_INIT(name, object, buffer, size) \
#define CK_RING_INIT(name, object, buffer, size) \
ck_ring_init_##name(object, buffer, size)
#define CK_RING_SIZE(name, object) \
#define CK_RING_SIZE(name, object) \
ck_ring_size_##name(object)
#define CK_RING_CAPACITY(name, object) \
#define CK_RING_CAPACITY(name, object) \
ck_ring_capacity_##name(object)
#define CK_RING_ENQUEUE_SPSC(name, object, value) \
#define CK_RING_ENQUEUE_SPSC_SIZE(name, object, value, s) \
ck_ring_enqueue_spsc_size_##name(object, value, s)
#define CK_RING_ENQUEUE_SPSC(name, object, value) \
ck_ring_enqueue_spsc_##name(object, value)
#define CK_RING_DEQUEUE_SPSC(name, object, value) \
#define CK_RING_DEQUEUE_SPSC(name, object, value) \
ck_ring_dequeue_spsc_##name(object, value)
#define CK_RING_DEQUEUE_SPMC(name, object, value) \
#define CK_RING_DEQUEUE_SPMC(name, object, value) \
ck_ring_dequeue_spmc_##name(object, value)
#define CK_RING_TRYDEQUEUE_SPMC(name, object, value) \
#define CK_RING_TRYDEQUEUE_SPMC(name, object, value) \
ck_ring_trydequeue_spmc_##name(object, value)
#define CK_RING_ENQUEUE_SPMC(name, object, value) \
#define CK_RING_ENQUEUE_SPMC_SIZE(name, object, value, s) \
ck_ring_enqueue_spmc_size_##name(object, value, s)
#define CK_RING_ENQUEUE_SPMC(name, object, value) \
ck_ring_enqueue_spmc_##name(object, value)
struct ck_ring {
@ -217,6 +249,50 @@ ck_ring_capacity(struct ck_ring *ring)
return ring->size;
}
/*
* Atomically enqueues the specified entry. Returns true on success, returns
* false if the ck_ring is full. This operation only support one active
* invocation at a time and works in the presence of a concurrent invocation
* of ck_ring_dequeue_spsc.
*
* This variant of ck_ring_enqueue_spsc returns the snapshot of queue length
* with respect to the linearization point. This can be used to extract ring
* size without incurring additional cacheline invalidation overhead from the
* writer.
*/
CK_CC_INLINE static bool
ck_ring_enqueue_spsc_size(struct ck_ring *ring,
void *entry,
unsigned int *size)
{
unsigned int consumer, producer, delta;
unsigned int mask = ring->mask;
consumer = ck_pr_load_uint(&ring->c_head);
producer = ring->p_tail;
delta = producer + 1;
*size = (producer - consumer) & mask;
if ((delta & mask) == (consumer & mask))
return false;
ring->ring[producer & mask] = entry;
/*
* Make sure to update slot value before indicating
* that the slot is available for consumption.
*/
ck_pr_fence_store();
ck_pr_store_uint(&ring->p_tail, delta);
return true;
}
/*
* Atomically enqueues the specified entry. Returns true on success, returns
* false if the ck_ring is full. This operation only support one active
* invocation at a time and works in the presence of a concurrent invocation
* of ck_ring_dequeue_spsc.
*/
CK_CC_INLINE static bool
ck_ring_enqueue_spsc(struct ck_ring *ring, void *entry)
{
@ -275,6 +351,32 @@ ck_ring_dequeue_spsc(struct ck_ring *ring, void *data)
return true;
}
/*
* Atomically enqueues the specified entry. Returns true on success, returns
* false if the ck_ring is full. This operation only support one active
* invocation at a time and works in the presence of up to UINT_MAX concurrent
* invocations of ck_ring_dequeue_spmc.
*
* This variant of ck_ring_enqueue_spmc returns the snapshot of queue length
* with respect to the linearization point. This can be used to extract ring
* size without incurring additional cacheline invalidation overhead from the
* writer.
*/
CK_CC_INLINE static bool
ck_ring_enqueue_spmc_size(struct ck_ring *ring,
void *entry,
unsigned int *size)
{
return ck_ring_enqueue_spsc_size(ring, entry, size);
}
/*
* Atomically enqueues the specified entry. Returns true on success, returns
* false if the ck_ring is full. This operation only support one active
* invocation at a time and works in the presence of up to UINT_MAX concurrent
* invocations of ck_ring_dequeue_spmc.
*/
CK_CC_INLINE static bool
ck_ring_enqueue_spmc(struct ck_ring *ring, void *entry)
{

@ -78,8 +78,8 @@ ck_spinlock_unlock_with_context(ck_spinlock_t *lock, void *context)
}
CK_COHORT_PROTOTYPE(basic,
ck_spinlock_t, ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context,
ck_spinlock_t, ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context)
ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context,
ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context)
struct cohort_record {
CK_COHORT_INSTANCE(basic) cohort;
@ -102,6 +102,7 @@ fairness(void *null)
unsigned int core;
CK_COHORT_INSTANCE(basic) *cohort;
if (aff_iterate_core(&a, &core)) {
perror("ERROR: Could not affine thread");
exit(EXIT_FAILURE);
@ -228,4 +229,3 @@ main(int argc, char *argv[])
return 0;
}

@ -1,25 +1,24 @@
#define LOCK_NAME "ck_cohort"
#define LOCK_DEFINE\
static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\
static ck_spinlock_fas_t local_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\
static void\
ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\
{\
(void)context;\
ck_spinlock_fas_lock(lock);\
}\
\
static void\
ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\
{\
(void)context;\
ck_spinlock_fas_unlock(lock);\
}\
CK_COHORT_PROTOTYPE(fas_fas,\
ck_spinlock_fas_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,\
ck_spinlock_fas_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context)\
#define LOCK_DEFINE \
static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; \
static ck_spinlock_fas_t local_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; \
static void \
ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context) \
{ \
(void)context; \
ck_spinlock_fas_lock(lock); \
} \
static void \
ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context) \
{ \
(void)context; \
ck_spinlock_fas_unlock(lock); \
} \
CK_COHORT_PROTOTYPE(fas_fas, \
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, \
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context) \
static CK_COHORT_INSTANCE(fas_fas) CK_CC_CACHELINE cohort = CK_COHORT_INITIALIZER
#define LOCK_INIT CK_COHORT_INIT(fas_fas, &cohort, &global_fas_lock, &local_fas_lock,\
#define LOCK_INIT CK_COHORT_INIT(fas_fas, &cohort, &global_fas_lock, &local_fas_lock, \
CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT)
#define LOCK CK_COHORT_LOCK(fas_fas, &cohort, NULL, NULL)
#define UNLOCK CK_COHORT_UNLOCK(fas_fas, &cohort, NULL, NULL)

@ -59,9 +59,16 @@ ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)
ck_spinlock_fas_unlock(lock);
}
CK_COHORT_PROTOTYPE(fas_fas,
ck_spinlock_fas_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,
ck_spinlock_fas_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context)
static bool
ck_spinlock_fas_trylock_with_context(ck_spinlock_fas_t *lock, void *context)
{
(void)context;
return ck_spinlock_fas_trylock(lock);
}
CK_COHORT_TRYLOCK_PROTOTYPE(fas_fas,
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_trylock_with_context,
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_trylock_with_context)
static CK_COHORT_INSTANCE(fas_fas) *cohorts;
static int n_cohorts;
@ -81,7 +88,15 @@ thread(void *null CK_CC_UNUSED)
cohort = cohorts + (core / (int)(a.delta)) % n_cohorts;
while (i--) {
CK_COHORT_LOCK(fas_fas, cohort, NULL, NULL);
if (i & 1) {
CK_COHORT_LOCK(fas_fas, cohort, NULL, NULL);
} else {
while (CK_COHORT_TRYLOCK(fas_fas, cohort, NULL, NULL, NULL) == false) {
ck_pr_stall();
}
}
{
l = ck_pr_load_uint(&locked);
if (l != 0) {

@ -1,7 +1,7 @@
.PHONY: check clean distribution
OBJECTS=ck_ring_spsc ck_ring_spsc_template ck_ring_spmc ck_ring_spmc_template
SIZE=65536
SIZE=16384
all: $(OBJECTS)

@ -66,7 +66,8 @@ test_spmc(void *c)
{
unsigned int observed = 0;
unsigned long previous = 0;
int i, j, tid;
unsigned int seed;
int i, k, j, tid;
(void)c;
if (aff_iterate(&a)) {
@ -81,6 +82,7 @@ test_spmc(void *c)
for (i = 0; i < ITERATIONS; i++) {
for (j = 0; j < size; j++) {
struct entry *o;
int spin;
/* Keep trying until we encounter at least one node. */
if (j & 1) {
@ -107,6 +109,13 @@ test_spmc(void *c)
ck_error("[%p] We dequeued twice.\n", (void *)o);
}
if ((i % 4) == 0) {
spin = common_rand_r(&seed) % 16384;
for (k = 0; k < spin; k++) {
ck_pr_stall();
}
}
free(o);
}
}
@ -120,6 +129,7 @@ test(void *c)
{
struct context *context = c;
struct entry *entry;
unsigned int s;
int i, j;
bool r;
ck_barrier_centralized_state_t sense =
@ -145,7 +155,18 @@ test(void *c)
entries[i].value = i;
entries[i].tid = 0;
r = ck_ring_enqueue_spmc(ring, entries + i);
if (i & 1) {
r = ck_ring_enqueue_spmc(ring, entries + i);
} else {
r = ck_ring_enqueue_spmc_size(ring,
entries + i, &s);
if ((int)s != i) {
ck_error("Size is %u, expected %d.\n",
s, size);
}
}
assert(r != false);
}
@ -180,7 +201,19 @@ test(void *c)
}
entry->tid = context->tid;
r = ck_ring_enqueue_spmc(ring + context->tid, entry);
if (i & 1) {
r = ck_ring_enqueue_spmc(ring + context->tid,
entry);
} else {
r = ck_ring_enqueue_spmc_size(ring + context->tid,
entry, &s);
if ((int)s >= size) {
ck_error("Size %u out of range of %d\n",
s, size);
}
}
assert(r == true);
}
}
@ -268,8 +301,21 @@ main(int argc, char *argv[])
entry->ref = 0;
/* Wait until queue is not full. */
while (ck_ring_enqueue_spmc(&ring_spmc, entry) == false)
ck_pr_stall();
if (l & 1) {
while (ck_ring_enqueue_spmc(&ring_spmc, entry) == false)
ck_pr_stall();
} else {
unsigned int s;
while (ck_ring_enqueue_spmc_size(&ring_spmc,
entry, &s) == false) {
ck_pr_stall();
}
if ((int)s >= (size * ITERATIONS * (nthr - 1))) {
ck_error("MPMC: Unexpected size of %u\n", s);
}
}
}
for (i = 0; i < nthr - 1; i++)

@ -121,6 +121,7 @@ test(void *c)
{
struct context *context = c;
struct entry entry;
unsigned int s;
int i, j;
bool r;
ck_barrier_centralized_state_t sense =
@ -141,7 +142,19 @@ test(void *c)
memset(&entry, 0, sizeof(entry));
entry.value = i;
r = CK_RING_ENQUEUE_SPMC(spmc_ring, ring, &entry);
if (i & 1) {
r = CK_RING_ENQUEUE_SPMC(spmc_ring, ring,
&entry);
} else {
r = CK_RING_ENQUEUE_SPMC_SIZE(spmc_ring, ring,
&entry, &s);
if ((int)s != i) {
ck_error("Size %u, expected %d.\n",
s, i);
}
}
assert(r != false);
}

@ -59,6 +59,7 @@ test(void *c)
{
struct context *context = c;
struct entry *entry;
unsigned int s;
int i, j;
bool r;
ck_barrier_centralized_state_t sense =
@ -84,7 +85,18 @@ test(void *c)
entries[i].value = i;
entries[i].tid = 0;
r = ck_ring_enqueue_spsc(ring, entries + i);
if (i & 1) {
r = ck_ring_enqueue_spsc(ring, entries + i);
} else {
r = ck_ring_enqueue_spsc_size(ring,
entries + i, &s);
if ((int)s != i) {
ck_error("Size is %u, expected %d\n",
s, i + 1);
}
}
assert(r != false);
}
@ -116,7 +128,18 @@ test(void *c)
}
entry->tid = context->tid;
r = ck_ring_enqueue_spsc(ring + context->tid, entry);
if (i & 1) {
r = ck_ring_enqueue_spsc(ring + context->tid,
entry);
} else {
r = ck_ring_enqueue_spsc_size(ring +
context->tid, entry, &s);
if ((int)s >= size) {
ck_error("Size %u is out of range %d\n",
s, size);
}
}
assert(r == true);
}
}

@ -60,6 +60,7 @@ test(void *c)
{
struct context *context = c;
struct entry entry;
unsigned int s;
int i, j;
bool r;
ck_barrier_centralized_state_t sense =
@ -85,7 +86,20 @@ test(void *c)
entries[i].value = i;
entries[i].tid = 0;
r = CK_RING_ENQUEUE_SPSC(entry_ring, ring, entries + i);
if (i & 1) {
r = CK_RING_ENQUEUE_SPSC(entry_ring,
ring, entries + i);
} else {
r = CK_RING_ENQUEUE_SPSC_SIZE(entry_ring,
ring, entries + i, &s);
if ((int)s != i) {
ck_error("Size is %u, expected %d\n",
s, i);
}
}
assert(r != false);
}
if (CK_RING_SIZE(entry_ring, ring) !=
@ -113,7 +127,20 @@ test(void *c)
}
entry.tid = context->tid;
r = CK_RING_ENQUEUE_SPSC(entry_ring, ring + context->tid, &entry);
if (i & 1) {
r = CK_RING_ENQUEUE_SPSC(entry_ring,
ring + context->tid, &entry);
} else {
r = CK_RING_ENQUEUE_SPSC_SIZE(entry_ring,
ring + context->tid, &entry, &s);
if ((int)s >= size) {
ck_error("Size %u is out of range %d\n",
s, size);
}
}
assert(r == true);
}
}

Loading…
Cancel
Save