Added support for systemless build (no pthreads).

Details:
- Added a configure option, --[enable|disable]-system, which determines
  whether the modest operating system dependencies in BLIS are included.
  The most notable example of this on Linux and BSD/OSX is the use of
  POSIX threads to ensure thread safety for when application-level
  threads call BLIS. When --disable-system is given, the bli_pthreads
  implementation is dummied out entirely, allowing the calling code
  within BLIS to remain unchanged. Why would anyone want to build BLIS
  like this? The motivating example was submitted via #454 in which a
  user wanted to build BLIS for a simulator such as gem5 where thread
  safety may not be a concern (and where the operating system is largely
  absent anyway). Thanks to Stepan Nassyr for suggesting this feature.
- Another, more minor side effect of the --disable-system option is that
  the implementation of bli_clock() unconditionally returns 0.0 instead
  of the time elapsed since some fixed point in the past. The reasoning
  for this is that if the operating system is truly minimal, the system
  function call upon which bli_clock() would normally be implemented
  (e.g. clock_gettime()) may not be available.
- Refactored preprocess-guarded code in bli_pthread.c and bli_pthread.h
  to remove redundancies.
- Removed old comments and commented #include of "bli_pthread_wrap.h"
  from bli_system.h.
- Documented bli_clock() and bli_clock_min_diff() in BLISObjectAPI.md
  and BLISTypedAPI.md, with a note that both are non-functional when
  BLIS is configured with --disable-system.
This commit is contained in:
Field G. Van Zee
2020-11-16 15:55:45 -06:00
parent 88ad841434
commit 9bb23e6c2a
11 changed files with 416 additions and 143 deletions

View File

@@ -61,6 +61,7 @@ but many others have contributed code and feedback, including
Stefanos Mavros @smavros
@nagsingh
Bhaskar Nallani @BhaskarNallani (AMD)
Stepan Nassyr @stepannassyr (Jülich Supercomputing Centre)
Nisanth Padinharepatt (AMD)
Ajay Panyala @ajaypanyala
Devangi Parikh @dnparikh (The University of Texas at Austin)

View File

@@ -45,6 +45,12 @@
// Enabled kernel sets (kernel_list)
@kernel_list_defines@
#if @enable_system@
#define BLIS_ENABLE_SYSTEM
#else
#define BLIS_DISABLE_SYSTEM
#endif
#if @enable_openmp@
#define BLIS_ENABLE_OPENMP
#endif

View File

@@ -117,6 +117,9 @@ LDFLAGS_PRESET := @ldflags_preset@
# The level of debugging info to generate.
DEBUG_TYPE := @debug_type@
# Whether operating system support was requested via --enable-system.
ENABLE_SYSTEM := @enable_system@
# The requested threading model.
THREADING_MODEL := @threading_model@
@@ -184,7 +187,8 @@ MK_ENABLE_MEMKIND := @enable_memkind@
# enabled.
SANDBOX := @sandbox@
# The name of the pthreads library.
# The name of the pthreads library. If --disable-system was given, then this
# variable is set to the empty value.
LIBPTHREAD := @libpthread@
# end of ifndef CONFIG_MK_INCLUDED conditional block

View File

@@ -500,7 +500,8 @@ LIBMEMKIND := -lmemkind
# Default linker flags.
# NOTE: -lpthread is needed unconditionally because BLIS uses pthread_once()
# to initialize itself in a thread-safe manner.
# to initialize itself in a thread-safe manner. The one exception to this
# rule: if --disable-system is given at configure-time, LIBPTHREAD is empty.
LDFLAGS := $(LDFLAGS_PRESET) $(LIBM) $(LIBPTHREAD)
# Add libmemkind to the link-time flags, if it was enabled at configure-time.
@@ -731,6 +732,10 @@ $(foreach c, $(CONFIG_LIST_FAM), $(eval $(call append-var-for,CPPROCFLAGS,$(c)))
# --- Threading flags ---
# NOTE: We don't have to explicitly omit -pthread when --disable-system is given
# since that option forces --enable-threading=none, and thus -pthread never gets
# added to begin with.
ifeq ($(CC_VENDOR),gcc)
ifeq ($(THREADING_MODEL),auto)
THREADING_MODEL := openmp

58
configure vendored
View File

@@ -168,6 +168,18 @@ print_usage()
echo " --disable-threading is specified, threading will be"
echo " disabled. The default is 'no'."
echo " "
echo " --enable-system, --disable-system"
echo " "
echo " Enable conventional operating system support, such as"
echo " pthreads for thread-safety. The default state is enabled."
echo " However, in rare circumstances you may wish to configure"
echo " BLIS for use with a minimal or nonexistent operating"
echo " system (e.g. hardware simulators). In these situations,"
echo " --disable-system may be used to jettison all compile-time"
echo " and link-time dependencies outside of the standard C"
echo " library. When disabled, this option also forces the use"
echo " of --disable-threading."
echo " "
echo " --disable-pba-pools, --enable-pba-pools"
echo " --disable-sba-pools, --enable-sba-pools"
echo " "
@@ -1071,13 +1083,19 @@ auto_detect()
config_defines=$(grep BLIS_CONFIG_ ${bli_cpuid_c_filepath} \
| sed -e 's/#ifdef /-D/g')
# Set the linker flags. We need pthreads because it is needed for
# parts of bli_arch.c unrelated to bli_arch_string(), which is called
# by the main() function in ${main_c}.
if [[ $is_win == no || "$cc_vendor" != "clang" ]]; then
# Set the linker flags. We typically need pthreads (or BLIS's homerolled
# equiavlent) because it is needed for parts of bli_arch.c unrelated to
# bli_arch_string(), which is called by the main() function in ${main_c}.
if [[ "$is_win" == "no" || "$cc_vendor" != "clang" ]]; then
ldflags="${LIBPTHREAD--lpthread}"
fi
# However, if --disable-system was given, we override the choice made above
# and do not use any pthread link flags.
if [[ "$enable_system" == "no" ]]; then
ldflags=
fi
# Compile the auto-detect program using source code inside the
# framework.
# NOTE: -D_GNU_SOURCE is needed to enable POSIX extensions to
@@ -1965,6 +1983,9 @@ main()
debug_type=''
debug_flag=''
# The system flag.
enable_system='yes'
# The threading flag.
threading_model='off'
@@ -2107,6 +2128,12 @@ main()
export-shared=*)
export_shared=${OPTARG#*=}
;;
enable-system)
enable_system='yes'
;;
disable-system)
enable_system='no'
;;
enable-threading=*)
threading_model=${OPTARG#*=}
;;
@@ -2865,6 +2892,19 @@ main()
exit 1
fi
# Check if we are building with or without operating system support.
if [ "x${enable_system}" = "xyes" ]; then
echo "${script_name}: enabling operating system support."
enable_system_01=1
else
echo "${script_name}: disabling operating system support."
echo "${script_name}: WARNING: all threading will be disabled!"
enable_system_01=0
# Force threading to be disabled.
threading_model='off'
fi
# Check the threading model flag and standardize its value, if needed.
# NOTE: 'omp' is deprecated but still supported; 'openmp' is preferred.
enable_openmp='no'
@@ -3125,7 +3165,13 @@ main()
# For Windows builds, clear the libpthread_esc variable so that
# no pthreads library is substituted into config.mk. (Windows builds
# employ an implementation of pthreads that is internal to BLIS.)
if [[ $is_win == yes && "$cc_vendor" == "clang" ]]; then
if [[ "$is_win" == "yes" && "$cc_vendor" == "clang" ]]; then
libpthread_esc=
fi
# We also clear the libpthread_esc variable for systemless builds
# (--disable-system).
if [[ "$enable_system" == "no" ]]; then
libpthread_esc=
fi
@@ -3220,6 +3266,7 @@ main()
| sed -e "s/@cflags_preset@/${cflags_preset_esc}/g" \
| sed -e "s/@ldflags_preset@/${ldflags_preset_esc}/g" \
| sed -e "s/@debug_type@/${debug_type}/g" \
| sed -e "s/@enable_system@/${enable_system}/g" \
| sed -e "s/@threading_model@/${threading_model}/g" \
| sed -e "s/@prefix@/${prefix_esc}/g" \
| sed -e "s/@exec_prefix@/${exec_prefix_esc}/g" \
@@ -3250,6 +3297,7 @@ main()
| perl -pe "s/\@config_name_define\@/${config_name_define}/g" \
| perl -pe "s/\@config_list_defines\@/${config_list_defines}/g" \
| perl -pe "s/\@kernel_list_defines\@/${kernel_list_defines}/g" \
| sed -e "s/@enable_system@/${enable_system_01}/g" \
| sed -e "s/@enable_openmp@/${enable_openmp_01}/g" \
| sed -e "s/@enable_pthreads@/${enable_pthreads_01}/g" \
| sed -e "s/@enable_jrir_slab@/${enable_jrir_slab_01}/g" \

View File

@@ -31,6 +31,7 @@
* [Specific configuration](BLISObjectAPI.md#specific-configuration)
* [General configuration](BLISObjectAPI.md#general-configuration)
* [Kernel information](BLISObjectAPI.md#kernel-information)
* [Clock functions](BLISObjectAPI.md#clock-functions)
* **[Example code](BLISObjectAPI.md#example-code)**
@@ -2235,6 +2236,54 @@ Possible microkernel types (ie: the return values for `bli_info_get_*_ukr_impl_s
* `BLIS_OPTIMIZED_UKERNEL` (`"optimzd"`): This value is returned when the queried microkernel is provided by an implementation that is neither reference nor virtual, and thus we assume the kernel author would deem it to be "optimized". Such a microkernel may not be optimal in the literal sense of the word, but nonetheless is _intended_ to be optimized, at least relative to the reference microkernels.
* `BLIS_NOTAPPLIC_UKERNEL` (`"notappl"`): This value is returned usually when performing a `gemmtrsm` or `trsm` microkernel type query for any `method` value that is not `BLIS_NAT` (ie: native). That is, induced methods cannot be (purely) used on `trsm`-based microkernels because these microkernels perform more a triangular inversion, which is not matrix multiplication.
## Clock functions
---
#### clock
```c
double bli_clock
(
void
);
```
Return the amount of time that has elapsed since some fixed time in the past. The return values of `bli_clock()` typically feature nanosecond precision, though this is not guaranteed.
**Note:** On Linux, `bli_clock()` is implemented in terms of `clock_gettime()` using the `clockid_t` value of `CLOCK_MONOTONIC`. On OS X, `bli_clock` is implemented in terms of `mach_absolute_time()`. And on Windows, `bli_clock` is implemented in terms of `QueryPerformanceFrequency()`. Please see [frame/base/bli_clock.c](https://github.com/flame/blis/blob/master/frame/base/bli_clock.c) for more details.
**Note:** This function is returns meaningless values when BLIS is configured with `--disable-system`.
---
#### clock_min_diff
```c
double bli_clock_min_diff
(
double time_prev_min,
double time_start
);
```
This function computes an intermediate value, `time_diff`, equal to `bli_clock() - time_start`, and then tentatively prepares to return the minimum value of `time_diff` and `time_min`. If that minimum value is extremely small (close to zero), the function returns `time_min` instead.
This function is meant to be used in conjuction with `bli_clock()` for
performance timing within applications--specifically in loops where only
the fastest timing is of interest. For example:
```c
double t_save = DBL_MAX;
for( i = 0; i < 3; ++i )
{
double t = bli_clock();
bli_gemm( ... );
t_save = bli_clock_min_diff( t_save, t );
}
double gflops = ( 2.0 * m * k * n ) / ( t_save * 1.0e9 );
```
This code calls `bli_gemm()` three times and computes the performance, in GFLOPS, of the fastest of the three executions.
---
# Example code
BLIS provides lots of example code in the [examples/oapi](https://github.com/flame/blis/tree/master/examples/oapi) directory of the BLIS source distribution. The example code in this directory is set up like a tutorial, and so we recommend starting from the beginning. Topics include creating and managing objects, printing vectors and matrices, setting and querying object properties, and calling a representative subset of the computational level-1v, -1m, -2, -3, and utility operations documented above. Please read the `README` contained within the `examples/oapi` directory for further details.

View File

@@ -26,6 +26,7 @@
* [Specific configuration](BLISTypedAPI.md#specific-configuration)
* [General configuration](BLISTypedAPI.md#general-configuration)
* [Kernel information](BLISTypedAPI.md#kernel-information)
* [Clock functions](BLISTypedAPI.md#clock-functions)
* **[Example code](BLISTypedAPI.md#example-code)**
@@ -1902,6 +1903,54 @@ char* bli_info_get_trmm3_impl_string( num_t dt );
char* bli_info_get_trsm_impl_string( num_t dt );
```
## Clock functions
---
#### clock
```c
double bli_clock
(
void
);
```
Return the amount of time that has elapsed since some fixed time in the past. The return values of `bli_clock()` typically feature nanosecond precision, though this is not guaranteed.
**Note:** On Linux, `bli_clock()` is implemented in terms of `clock_gettime()` using the `clockid_t` value of `CLOCK_MONOTONIC`. On OS X, `bli_clock` is implemented in terms of `mach_absolute_time()`. And on Windows, `bli_clock` is implemented in terms of `QueryPerformanceFrequency()`. Please see [frame/base/bli_clock.c](https://github.com/flame/blis/blob/master/frame/base/bli_clock.c) for more details.
**Note:** This function is returns meaningless values when BLIS is configured with `--disable-system`.
---
#### clock_min_diff
```c
double bli_clock_min_diff
(
double time_prev_min,
double time_start
);
```
This function computes an intermediate value, `time_diff`, equal to `bli_clock() - time_start`, and then tentatively prepares to return the minimum value of `time_diff` and `time_min`. If that minimum value is extremely small (close to zero), the function returns `time_min` instead.
This function is meant to be used in conjuction with `bli_clock()` for
performance timing within applications--specifically in loops where only
the fastest timing is of interest. For example:
```c
double t_save = DBL_MAX;
for( i = 0; i < 3; ++i )
{
double t = bli_clock();
bli_gemm( ... );
t_save = bli_clock_min_diff( t_save, t );
}
double gflops = ( 2.0 * m * k * n ) / ( t_save * 1.0e9 );
```
This code calls `bli_gemm()` three times and computes the performance, in GFLOPS, of the fastest of the three executions.
---
# Example code
BLIS provides lots of example code in the [examples/tapi](https://github.com/flame/blis/tree/master/examples/tapi) directory of the BLIS source distribution. The example code in this directory is set up like a tutorial, and so we recommend starting from the beginning. Topics include printing vectors and matrices and calling a representative subset of the computational level-1v, -1m, -2, -3, and utility operations documented above. Please read the `README` contained within the `examples/tapi` directory for further details.

View File

@@ -64,6 +64,18 @@ double bli_clock_min_diff( double time_min, double time_start )
return time_min;
}
#ifdef BLIS_DISABLE_SYSTEM
// --- Begin systemless definitions --------------------------------------------
double bli_clock_helper()
{
return 0.0;
}
// --- End systemless definitions ----------------------------------------------
#else
// --- Begin system definitions ------------------------------------------------
#if BLIS_OS_WINDOWS
// --- Begin Windows build definitions -----------------------------------------
@@ -135,3 +147,6 @@ double bli_clock_helper()
// --- End Linux build definitions ---------------------------------------------
#endif
// --- End system definitions --------------------------------------------------
#endif

View File

@@ -123,10 +123,5 @@
#include <time.h>
#endif
// POSIX threads are unconditionally required, regardless of whether
// multithreading is enabled via pthreads or OpenMP (or disabled).
// If pthreads is not available (Windows), then fake it.
//#include "bli_pthread_wrap.h"
#endif

View File

@@ -36,9 +36,142 @@
#include "blis.h"
#include <errno.h>
#if defined(BLIS_DISABLE_SYSTEM)
#if defined(_MSC_VER)
// This branch defines a pthread-like API, bli_pthread_*(), and implements it
// in terms of "dummy" code that doesn't depend on POSIX threads or any other
// threading mechanism. See issue #454 to see the use case that prompted this
// feature.
// NOTE: THIS CODE DOES NOT IMPLEMENT THREADING AND IS NOT THREAD-SAFE!
// -- pthread_create(), pthread_join() --
int bli_pthread_create
(
bli_pthread_t* thread,
const bli_pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg
)
{
//return pthread_create( thread, attr, start_routine, arg );
start_routine( arg );
return 0;
}
int bli_pthread_join
(
bli_pthread_t thread,
void** retval
)
{
//return pthread_join( thread, retval );
return 0;
}
// -- pthread_mutex_*() --
int bli_pthread_mutex_init
(
bli_pthread_mutex_t* mutex,
const bli_pthread_mutexattr_t* attr
)
{
//return pthread_mutex_init( mutex, attr );
return 0;
}
int bli_pthread_mutex_destroy
(
bli_pthread_mutex_t* mutex
)
{
//return pthread_mutex_destroy( mutex );
return 0;
}
int bli_pthread_mutex_lock
(
bli_pthread_mutex_t* mutex
)
{
//return pthread_mutex_lock( mutex );
return 0;
}
int bli_pthread_mutex_trylock
(
bli_pthread_mutex_t* mutex
)
{
//return pthread_mutex_trylock( mutex );
return 0;
}
int bli_pthread_mutex_unlock
(
bli_pthread_mutex_t* mutex
)
{
//return pthread_mutex_unlock( mutex );
return 0;
}
// -- pthread_cond_*() --
int bli_pthread_cond_init
(
bli_pthread_cond_t* cond,
const bli_pthread_condattr_t* attr
)
{
//return pthread_cond_init( cond, attr );
return 0;
}
int bli_pthread_cond_destroy
(
bli_pthread_cond_t* cond
)
{
//return pthread_cond_destroy( cond );
return 0;
}
int bli_pthread_cond_wait
(
bli_pthread_cond_t* cond,
bli_pthread_mutex_t* mutex
)
{
//return pthread_cond_wait( cond, mutex );
return 0;
}
int bli_pthread_cond_broadcast
(
bli_pthread_cond_t* cond
)
{
//return pthread_cond_broadcast( cond );
return 0;
}
// -- pthread_once() --
void bli_pthread_once
(
bli_pthread_once_t* once,
void (*init)(void)
)
{
//pthread_once( once, init );
init();
}
#elif defined(_MSC_VER) // !defined(BLIS_DISABLE_SYSTEM)
#include <errno.h>
// This branch defines a pthread-like API, bli_pthread_*(), and implements it
// in terms of Windows API calls.
@@ -194,7 +327,7 @@ int bli_pthread_join
return 0;
}
#else // !defined(_MSC_VER)
#else // !defined(BLIS_DISABLE_SYSTEM) && !defined(_MSC_VER)
// This branch defines a pthreads-like API, bli_pthreads_*(), and implements it
// in terms of the corresponding pthreads_*() types, macros, and function calls.
@@ -317,9 +450,44 @@ void bli_pthread_once
#endif // _MSC_VER
// -- pthread_barrier_*() --
#if defined(__APPLE__) || defined(_MSC_VER)
#if defined(BLIS_DISABLE_SYSTEM)
int bli_pthread_barrier_init
(
bli_pthread_barrier_t* barrier,
const bli_pthread_barrierattr_t* attr,
unsigned int count
)
{
//return pthread_barrier_init( barrier, attr, count );
return 0;
}
int bli_pthread_barrier_destroy
(
bli_pthread_barrier_t* barrier
)
{
//return pthread_barrier_destroy( barrier );
return 0;
}
int bli_pthread_barrier_wait
(
bli_pthread_barrier_t* barrier
)
{
//return pthread_barrier_wait( barrier );
return 0;
}
#elif defined(__APPLE__) || defined(_MSC_VER) // !defined(BLIS_DISABLE_SYSTEM)
#include <errno.h>
// For OS X and Windows, we define barriers ourselves in terms of the rest
// of the API, though for slightly different reasons: For Windows, we must
@@ -382,7 +550,7 @@ int bli_pthread_barrier_wait
}
}
#else // !( defined(__APPLE__) || defined(_MSC_VER) )
#else // !defined(BLIS_DISABLE_SYSTEM) && !defined(__APPLE__) && !defined(_MSC_VER)
// Linux environments implement the pthread_barrier* sub-API. So, if we're
// on Linux, we can simply call those functions, just as we did before for
@@ -414,4 +582,5 @@ int bli_pthread_barrier_wait
return pthread_barrier_wait( barrier );
}
#endif // defined(__APPLE__) || defined(_MSC_VER)
#endif

View File

@@ -36,113 +36,53 @@
#ifndef BLIS_PTHREAD_H
#define BLIS_PTHREAD_H
#if defined(_MSC_VER)
// -- Type and macro definitions -----------------------------------------------
#if defined(BLIS_DISABLE_SYSTEM)
// This branch defines a pthread-like API, bli_pthread_*(), and implements it
// in terms of "dummy" code that doesn't depend on POSIX threads or any other
// threading mechanism. See issue #454 to see the use case that prompted this
// feature.
// NOTE: THIS CODE DOES NOT IMPLEMENT THREADING AND IS NOT THREAD-SAFE!
// -- pthread types --
typedef int bli_pthread_t;
typedef int bli_pthread_attr_t;
typedef int bli_pthread_mutex_t;
typedef int bli_pthread_mutexattr_t;
typedef int bli_pthread_cond_t;
typedef int bli_pthread_condattr_t;
typedef int bli_pthread_once_t;
typedef int bli_pthread_barrier_t;
typedef int bli_pthread_barrierattr_t;
// -- pthreads macros --
#define BLIS_PTHREAD_MUTEX_INITIALIZER 0
#define BLIS_PTHREAD_COND_INITIALIZER 0
#define BLIS_PTHREAD_ONCE_INIT 0
#elif defined(_MSC_VER) // !defined(BLIS_DISABLE_SYSTEM)
// This branch defines a pthread-like API, bli_pthread_*(), and implements it
// in terms of Windows API calls.
// -- pthread_mutex_*() --
typedef SRWLOCK bli_pthread_mutex_t;
typedef void bli_pthread_mutexattr_t;
#define BLIS_PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
BLIS_EXPORT_BLIS int bli_pthread_mutex_init
(
bli_pthread_mutex_t* mutex,
const bli_pthread_mutexattr_t* attr
);
BLIS_EXPORT_BLIS int bli_pthread_mutex_destroy
(
bli_pthread_mutex_t* mutex
);
BLIS_EXPORT_BLIS int bli_pthread_mutex_lock
(
bli_pthread_mutex_t* mutex
);
BLIS_EXPORT_BLIS int bli_pthread_mutex_trylock
(
bli_pthread_mutex_t* mutex
);
BLIS_EXPORT_BLIS int bli_pthread_mutex_unlock
(
bli_pthread_mutex_t* mutex
);
// -- pthread_once_*() --
typedef INIT_ONCE bli_pthread_once_t;
#define BLIS_PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
BLIS_EXPORT_BLIS void bli_pthread_once
(
bli_pthread_once_t* once,
void (*init)(void)
);
// -- pthread_cond_*() --
typedef CONDITION_VARIABLE bli_pthread_cond_t;
typedef void bli_pthread_condattr_t;
#define BLIS_PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
BLIS_EXPORT_BLIS int bli_pthread_cond_init
(
bli_pthread_cond_t* cond,
const bli_pthread_condattr_t* attr
);
BLIS_EXPORT_BLIS int bli_pthread_cond_destroy
(
bli_pthread_cond_t* cond
);
BLIS_EXPORT_BLIS int bli_pthread_cond_wait
(
bli_pthread_cond_t* cond,
bli_pthread_mutex_t* mutex
);
BLIS_EXPORT_BLIS int bli_pthread_cond_broadcast
(
bli_pthread_cond_t* cond
);
// -- pthread_create(), pthread_join() --
// -- pthread types --
typedef struct
{
HANDLE handle;
void* retval;
} bli_pthread_t;
typedef void bli_pthread_attr_t;
BLIS_EXPORT_BLIS int bli_pthread_create
(
bli_pthread_t* thread,
const bli_pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg
);
BLIS_EXPORT_BLIS int bli_pthread_join
(
bli_pthread_t thread,
void** retval
);
// -- pthread_barrier_*() --
typedef void bli_pthread_barrierattr_t;
typedef SRWLOCK bli_pthread_mutex_t;
typedef void bli_pthread_mutexattr_t;
typedef CONDITION_VARIABLE bli_pthread_cond_t;
typedef void bli_pthread_condattr_t;
typedef INIT_ONCE bli_pthread_once_t;
typedef struct
{
bli_pthread_mutex_t mutex;
@@ -150,25 +90,15 @@ typedef struct
int count;
int tripCount;
} bli_pthread_barrier_t;
typedef void bli_pthread_barrierattr_t;
BLIS_EXPORT_BLIS int bli_pthread_barrier_init
(
bli_pthread_barrier_t* barrier,
const bli_pthread_barrierattr_t* attr,
unsigned int count
);
// -- pthreads macros --
BLIS_EXPORT_BLIS int bli_pthread_barrier_destroy
(
bli_pthread_barrier_t* barrier
);
#define BLIS_PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
#define BLIS_PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
#define BLIS_PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
BLIS_EXPORT_BLIS int bli_pthread_barrier_wait
(
bli_pthread_barrier_t* barrier
);
#else // !defined(_MSC_VER)
#else // !defined(BLIS_DISABLE_SYSTEM) && !defined(_MSC_VER)
#include <pthread.h>
@@ -177,13 +107,13 @@ BLIS_EXPORT_BLIS int bli_pthread_barrier_wait
// -- pthread types --
typedef pthread_t bli_pthread_t;
typedef pthread_attr_t bli_pthread_attr_t;
typedef pthread_mutex_t bli_pthread_mutex_t;
typedef pthread_mutexattr_t bli_pthread_mutexattr_t;
typedef pthread_cond_t bli_pthread_cond_t;
typedef pthread_condattr_t bli_pthread_condattr_t;
typedef pthread_once_t bli_pthread_once_t;
typedef pthread_t bli_pthread_t;
typedef pthread_attr_t bli_pthread_attr_t;
typedef pthread_mutex_t bli_pthread_mutex_t;
typedef pthread_mutexattr_t bli_pthread_mutexattr_t;
typedef pthread_cond_t bli_pthread_cond_t;
typedef pthread_condattr_t bli_pthread_condattr_t;
typedef pthread_once_t bli_pthread_once_t;
#if defined(__APPLE__)
@@ -194,10 +124,10 @@ typedef void bli_pthread_barrierattr_t;
typedef struct
{
bli_pthread_mutex_t mutex;
bli_pthread_cond_t cond;
int count;
int tripCount;
bli_pthread_mutex_t mutex;
bli_pthread_cond_t cond;
int count;
int tripCount;
} bli_pthread_barrier_t;
#else
@@ -217,6 +147,10 @@ typedef pthread_barrierattr_t bli_pthread_barrierattr_t;
#define BLIS_PTHREAD_COND_INITIALIZER PTHREAD_COND_INITIALIZER
#define BLIS_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
#endif
// -- Function definitions -----------------------------------------------------
// -- pthread_create(), pthread_join() --
BLIS_EXPORT_BLIS int bli_pthread_create
@@ -312,6 +246,4 @@ BLIS_EXPORT_BLIS int bli_pthread_barrier_wait
bli_pthread_barrier_t* barrier
);
#endif // _MSC_VER
#endif // BLIS_PTHREAD_H