mirror of
https://github.com/amd/blis.git
synced 2026-04-20 07:38:53 +00:00
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:
1
CREDITS
1
CREDITS
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
58
configure
vendored
@@ -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" \
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user