For this series: Reviewed-and-tested-by: Bill Fischofer <[email protected]>
On Fri, Jun 12, 2015 at 6:56 AM, Petri Savolainen < [email protected]> wrote: > Thread IDs and masks are used to control thread access to various > resources. Linux generic implementation reuse cpumask implementation. > > Signed-off-by: Petri Savolainen <[email protected]> > --- > include/odp.h | 1 + > include/odp/api/thrmask.h | 229 > +++++++++++++++++++++ > platform/linux-generic/Makefile.am | 4 + > .../linux-generic/include/odp/plat/thrmask_types.h | 48 +++++ > platform/linux-generic/include/odp/thrmask.h | 36 ++++ > platform/linux-generic/odp_thrmask.c | 102 +++++++++ > 6 files changed, 420 insertions(+) > create mode 100644 include/odp/api/thrmask.h > create mode 100644 platform/linux-generic/include/odp/plat/thrmask_types.h > create mode 100644 platform/linux-generic/include/odp/thrmask.h > create mode 100644 platform/linux-generic/odp_thrmask.c > > diff --git a/include/odp.h b/include/odp.h > index 2bac510..fe1dc74 100644 > --- a/include/odp.h > +++ b/include/odp.h > @@ -53,6 +53,7 @@ extern "C" { > #include <odp/event.h> > #include <odp/random.h> > #include <odp/errno.h> > +#include <odp/thrmask.h> > > #ifdef __cplusplus > } > diff --git a/include/odp/api/thrmask.h b/include/odp/api/thrmask.h > new file mode 100644 > index 0000000..ebc31f2 > --- /dev/null > +++ b/include/odp/api/thrmask.h > @@ -0,0 +1,229 @@ > +/* Copyright (c) 2015, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +/** > + * @file > + * > + * ODP thread masks > + */ > + > +#ifndef ODP_API_THRMASK_H_ > +#define ODP_API_THRMASK_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include <odp/std_types.h> > + > +/** @addtogroup odp_thread > + * Thread mask operations. > + * @{ > + */ > + > +/** > + * @def ODP_THRMASK_STR_SIZE > + * Minimum size of output buffer for odp_thrmask_to_str() > + */ > + > +/** > + * Add thread mask bits from a string > + * > + * @param[out] mask Thread mask to modify > + * @param str Hexadecimal digits in a string. Thread ID zero is > located > + * at the least significant bit (0x1). > + */ > +void odp_thrmask_from_str(odp_thrmask_t *mask, const char *str); > + > +/** > + * Format Thread mask as a string of hexadecimal digits > + * > + * @param mask Thread mask to format > + * @param[out] str Output buffer (use ODP_THRMASK_STR_SIZE) > + * @param size Size of output buffer > + * > + * @return number of characters written (including terminating null char) > + * @retval <0 on failure (buffer too small) > + */ > +int32_t odp_thrmask_to_str(const odp_thrmask_t *mask, char *str, int32_t > size); > + > +/** > + * Clear entire thread mask > + * @param mask Thread mask to clear > + */ > +void odp_thrmask_zero(odp_thrmask_t *mask); > + > +/** > + * Add thread to mask > + * @param mask Thread mask to update > + * @param thr Thread ID > + */ > +void odp_thrmask_set(odp_thrmask_t *mask, int thr); > + > +/** > + * Set all threads in mask > + * > + * Set all possible threads in the mask. All threads from 0 to > + * odp_thrmask_count() minus one are set, regardless of which threads are > + * actually active. > + * > + * @param mask Thread mask to set > + */ > +void odp_thrmask_setall(odp_thrmask_t *mask); > + > +/** > + * Remove thread from mask > + * @param mask Thread mask to update > + * @param thr Thread ID > + */ > +void odp_thrmask_clr(odp_thrmask_t *mask, int thr); > + > +/** > + * Test if thread is a member of mask > + * > + * @param mask Thread mask to test > + * @param thr Thread ID > + * > + * @return non-zero if set > + * @retval 0 if not set > + */ > +int odp_thrmask_isset(const odp_thrmask_t *mask, int thr); > + > +/** > + * Count number of threads set in mask > + * > + * @param mask Thread mask > + * > + * @return population count > + */ > +int odp_thrmask_count(const odp_thrmask_t *mask); > + > +/** > + * Member-wise AND over two thread masks > + * > + * @param dest Destination thread mask (may be one of the source > masks) > + * @param src1 Source thread mask 1 > + * @param src2 Source thread mask 2 > + */ > +void odp_thrmask_and(odp_thrmask_t *dest, const odp_thrmask_t *src1, > + const odp_thrmask_t *src2); > + > +/** > + * Member-wise OR over two thread masks > + * > + * @param dest Destination thread mask (may be one of the source > masks) > + * @param src1 Source thread mask 1 > + * @param src2 Source thread mask 2 > + */ > +void odp_thrmask_or(odp_thrmask_t *dest, const odp_thrmask_t *src1, > + const odp_thrmask_t *src2); > + > +/** > + * Member-wise XOR over two thread masks > + * > + * @param dest Destination thread mask (may be one of the source > masks) > + * @param src1 Source thread mask 1 > + * @param src2 Source thread mask 2 > + */ > +void odp_thrmask_xor(odp_thrmask_t *dest, const odp_thrmask_t *src1, > + const odp_thrmask_t *src2); > + > +/** > + * Test if two thread masks contain the same threads > + * > + * @param mask1 Thread mask 1 > + * @param mask2 Thread mask 2 > + * > + * @retval non-zero if thread masks equal > + * @retval 0 if thread masks not equal > + */ > +int odp_thrmask_equal(const odp_thrmask_t *mask1, > + const odp_thrmask_t *mask2); > + > +/** > + * Copy a thread mask > + * > + * @param dest Destination thread mask > + * @param src Source thread mask > + */ > +void odp_thrmask_copy(odp_thrmask_t *dest, const odp_thrmask_t *src); > + > +/** > + * Find first set thread in mask > + * > + * @param mask thread mask > + * > + * @return Thread ID > + * @retval <0 if no thread found > + */ > +int odp_thrmask_first(const odp_thrmask_t *mask); > + > +/** > + * Find last set thread in mask > + * > + * @param mask Thread mask > + * > + * @return Thread ID > + * @retval <0 if no thread found > + */ > +int odp_thrmask_last(const odp_thrmask_t *mask); > + > +/** > + * Find next set thread in mask > + * > + * Finds the next thread in the thread mask, starting at the thread > passed. > + * Use with odp_thrmask_first to traverse a thread mask, e.g. > + * > + * int thr = odp_thrmask_first(&mask); > + * while (0 <= thr) { > + * ... > + * ... > + * thr = odp_thrmask_next(&mask, thr); > + * } > + * > + * @param mask Thread mask > + * @param thr Thread to start from > + * > + * @return Thread ID > + * @retval <0 if no thread found > + * > + * @see odp_thrmask_first() > + */ > +int odp_thrmask_next(const odp_thrmask_t *mask, int thr); > + > +/** > + * Worker thread mask > + * > + * Initializes thread mask with current worker threads and returns the > count > + * set. > + * > + * @param[out] mask Thread mask to initialize > + * > + * @return Number of threads in the mask > + */ > +int odp_thrmask_worker(odp_thrmask_t *mask); > + > +/** > + * Control thread mask > + * > + * Initializes thread mask with current control threads and returns the > count > + * set. > + * > + * @param[out] mask Thread mask to initialize > + * > + * @return Number of threads in the mask > + */ > +int odp_thrmask_control(odp_thrmask_t *mask); > + > +/** > + * @} > + */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > diff --git a/platform/linux-generic/Makefile.am > b/platform/linux-generic/Makefile.am > index 66f0474..0b4695b 100644 > --- a/platform/linux-generic/Makefile.am > +++ b/platform/linux-generic/Makefile.am > @@ -42,6 +42,7 @@ odpinclude_HEADERS = \ > $(top_srcdir)/platform/linux-generic/include/odp/sync.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/system_info.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/thread.h \ > + > $(top_srcdir)/platform/linux-generic/include/odp/thrmask.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/ticketlock.h \ > $(top_srcdir)/platform/linux-generic/include/odp/time.h \ > $(top_srcdir)/platform/linux-generic/include/odp/timer.h > \ > @@ -66,6 +67,7 @@ odpplatinclude_HEADERS = \ > > $(top_srcdir)/platform/linux-generic/include/odp/plat/shared_memory_types.h > \ > > $(top_srcdir)/platform/linux-generic/include/odp/plat/spinlock_types.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/plat/strong_types.h \ > + > $(top_srcdir)/platform/linux-generic/include/odp/plat/thrmask_types.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/plat/ticketlock_types.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/plat/timer_types.h \ > > $(top_srcdir)/platform/linux-generic/include/odp/plat/version_types.h > @@ -102,6 +104,7 @@ odpapiinclude_HEADERS = \ > $(top_srcdir)/include/odp/api/sync.h \ > $(top_srcdir)/include/odp/api/system_info.h \ > $(top_srcdir)/include/odp/api/thread.h \ > + $(top_srcdir)/include/odp/api/thrmask.h \ > $(top_srcdir)/include/odp/api/ticketlock.h \ > $(top_srcdir)/include/odp/api/time.h \ > $(top_srcdir)/include/odp/api/timer.h \ > @@ -165,6 +168,7 @@ __LIB__libodp_la_SOURCES = \ > odp_spinlock.c \ > odp_system_info.c \ > odp_thread.c \ > + odp_thrmask.c \ > odp_ticketlock.c \ > odp_time.c \ > odp_timer.c \ > diff --git a/platform/linux-generic/include/odp/plat/thrmask_types.h > b/platform/linux-generic/include/odp/plat/thrmask_types.h > new file mode 100644 > index 0000000..30915c9 > --- /dev/null > +++ b/platform/linux-generic/include/odp/plat/thrmask_types.h > @@ -0,0 +1,48 @@ > +/* Copyright (c) 2015, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +/** > + * @file > + * > + * ODP thread masks > + */ > + > +#ifndef ODP_THRMASK_TYPES_H_ > +#define ODP_THRMASK_TYPES_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** @addtogroup odp_thread > + * @{ > + */ > + > +#include <odp/plat/cpumask_types.h> > + > +/** > + * Minimum size of output buffer for odp_thrmask_to_str() > + */ > +#define ODP_THRMASK_STR_SIZE ODP_CPUMASK_STR_SIZE > + > +/** > + * Thread mask > + * > + * Don't access directly, use access functions. > + */ > +typedef struct odp_thrmask_t { > + odp_cpumask_t m; /**< @private Mask*/ > +} odp_thrmask_t; > + > +/** > + * @} > + */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > diff --git a/platform/linux-generic/include/odp/thrmask.h > b/platform/linux-generic/include/odp/thrmask.h > new file mode 100644 > index 0000000..0e98ece > --- /dev/null > +++ b/platform/linux-generic/include/odp/thrmask.h > @@ -0,0 +1,36 @@ > +/* Copyright (c) 2015, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +/** > + * @file > + * > + * ODP thread masks > + */ > + > +#ifndef ODP_PLAT_THRMASK_H_ > +#define ODP_PLAT_THRMASK_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include <odp/plat/thrmask_types.h> > + > +/** @ingroup odp_thread > + * @{ > + */ > + > +/** > + * @} > + */ > + > +#include <odp/api/thrmask.h> > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > diff --git a/platform/linux-generic/odp_thrmask.c > b/platform/linux-generic/odp_thrmask.c > new file mode 100644 > index 0000000..d10bbf1 > --- /dev/null > +++ b/platform/linux-generic/odp_thrmask.c > @@ -0,0 +1,102 @@ > +/* Copyright (c) 2015, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#endif > +#include <sched.h> > + > +#include <odp/config.h> > +#include <odp/thrmask.h> > +#include <odp/cpumask.h> > + > +#if CPU_SETSIZE < ODP_CONFIG_MAX_THREADS > +#error Thread mask does not fit all thread IDs > +#endif > + > +void odp_thrmask_from_str(odp_thrmask_t *mask, const char *str) > +{ > + odp_cpumask_from_str(&mask->m, str); > +} > + > +int32_t odp_thrmask_to_str(const odp_thrmask_t *mask, char *str, int32_t > size) > +{ > + return odp_cpumask_to_str(&mask->m, str, size); > +} > + > +void odp_thrmask_zero(odp_thrmask_t *mask) > +{ > + odp_cpumask_zero(&mask->m); > +} > + > +void odp_thrmask_set(odp_thrmask_t *mask, int thr) > +{ > + odp_cpumask_set(&mask->m, thr); > +} > + > +void odp_thrmask_setall(odp_thrmask_t *mask) > +{ > + odp_cpumask_setall(&mask->m); > +} > + > +void odp_thrmask_clr(odp_thrmask_t *mask, int thr) > +{ > + odp_cpumask_clr(&mask->m, thr); > +} > + > +int odp_thrmask_isset(const odp_thrmask_t *mask, int thr) > +{ > + return odp_cpumask_isset(&mask->m, thr); > +} > + > +int odp_thrmask_count(const odp_thrmask_t *mask) > +{ > + return odp_cpumask_count(&mask->m); > +} > + > +void odp_thrmask_and(odp_thrmask_t *dest, const odp_thrmask_t *src1, > + const odp_thrmask_t *src2) > +{ > + odp_cpumask_and(&dest->m, &src1->m, &src2->m); > +} > + > +void odp_thrmask_or(odp_thrmask_t *dest, const odp_thrmask_t *src1, > + const odp_thrmask_t *src2) > +{ > + odp_cpumask_or(&dest->m, &src1->m, &src2->m); > +} > + > +void odp_thrmask_xor(odp_thrmask_t *dest, const odp_thrmask_t *src1, > + const odp_thrmask_t *src2) > +{ > + odp_cpumask_xor(&dest->m, &src1->m, &src2->m); > +} > + > +int odp_thrmask_equal(const odp_thrmask_t *mask1, > + const odp_thrmask_t *mask2) > +{ > + return odp_cpumask_equal(&mask1->m, &mask2->m); > +} > + > +void odp_thrmask_copy(odp_thrmask_t *dest, const odp_thrmask_t *src) > +{ > + odp_cpumask_copy(&dest->m, &src->m); > +} > + > +int odp_thrmask_first(const odp_thrmask_t *mask) > +{ > + return odp_cpumask_first(&mask->m); > +} > + > +int odp_thrmask_last(const odp_thrmask_t *mask) > +{ > + return odp_cpumask_last(&mask->m); > +} > + > +int odp_thrmask_next(const odp_thrmask_t *mask, int thr) > +{ > + return odp_cpumask_next(&mask->m, thr); > +} > -- > 2.4.3 > > _______________________________________________ > lng-odp mailing list > [email protected] > https://lists.linaro.org/mailman/listinfo/lng-odp >
_______________________________________________ lng-odp mailing list [email protected] https://lists.linaro.org/mailman/listinfo/lng-odp
