Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Sep 2007 08:14:37 -0700
From:      Arun Sharma <arun-public@sharma-home.net>
To:        tbb-develop@lists.sourceforge.net
Cc:        freebsd-hackers@freebsd.org, kfarnham@users.sourceforge.net
Subject:   TBB support for FreeBSD
Message-ID:  <20070929151437.GA35489@sharma-home.net>

next in thread | raw e-mail | index | archive | help
FreeBSD support - tested on 7.0-CURRENT/amd64.
Should apply cleanly to tbb20_20070815oss_src.tar.gz.

Signed-off-by: Arun Sharma <arun-public@sharma-home.net>

diff -r 627751b671bb -r ac2c116b7cee build/common.inc
--- a/build/common.inc	Sat Sep 29 16:18:03 2007 -0700
+++ b/build/common.inc	Sat Sep 29 16:51:17 2007 -0700
@@ -37,6 +37,9 @@ ifndef tbb_os
   endif
   ifeq ($(OS), Darwin)
    export tbb_os=macos
+  endif
+  ifeq ($(OS), FreeBSD)
+   export tbb_os=freebsd
   endif
  endif
 endif
diff -r 627751b671bb -r ac2c116b7cee build/freebsd.gcc.inc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/freebsd.gcc.inc	Sat Sep 29 16:51:17 2007 -0700
@@ -0,0 +1,98 @@
+# Copyright 2005-2007 Intel Corporation.  All Rights Reserved.
+#
+# This file is part of Threading Building Blocks.
+#
+# Threading Building Blocks is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation.
+#
+# Threading Building Blocks is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Threading Building Blocks; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# As a special exception, you may use this file as part of a free software
+# library without restriction.  Specifically, if other files instantiate
+# templates or use macros or inline functions from this file, or you compile
+# this file and link it with other files to produce an executable, this
+# file does not by itself cause the resulting executable to be covered by
+# the GNU General Public License.  This exception does not however
+# invalidate any other reasons why the executable file might be covered by
+# the GNU General Public License.
+
+COMPILE_ONLY = -c -MMD
+PREPROC_ONLY = -E -MMD
+INCLUDE_KEY = -I
+DEFINE_KEY = -D
+OUTPUT_KEY = -o #
+OUTPUTOBJ_KEY = -o #
+PIC_KEY = -fPIC
+WARNING_KEY = -Wall -Werror
+DYLIB_KEY = -shared
+LIBDL =
+
+TBB_NOSTRICT = 1
+
+CPLUS = g++ 
+INCLUDES += -I$(tbb_root)/src/tbb -I$(tbb_root)/include -I$(tbb_root)/src
+LIB_LINK_FLAGS = -shared
+LIBS = -lpthread -lrt
+C_FLAGS = $(CPLUS_FLAGS) -x c
+
+ifeq ($(cfg), release)
+        CPLUS_FLAGS = -DDO_ITT_NOTIFY -O2 -DUSE_PTHREAD
+endif
+ifeq ($(cfg), debug)
+        CPLUS_FLAGS = -DTBB_DO_ASSERT -DDO_ITT_NOTIFY -g -O0 -DUSE_PTHREAD
+endif
+
+ASM=
+ASM_FLAGS=
+
+TBB_ASM.OBJ=
+
+ifeq (itanium,$(arch))
+# Position-independent code (PIC) is a must for IA-64
+    CPLUS_FLAGS += $(PIC_KEY)
+    $(PIC_KEY) = 
+endif 
+
+ifeq (em64t,$(arch))
+    CPLUS_FLAGS += -m64
+    LIB_LINK_FLAGS += -m64
+endif 
+
+ifeq (ia32,$(arch))
+    CPLUS_FLAGS += -m32
+    LIB_LINK_FLAGS += -m32
+endif 
+
+#------------------------------------------------------------------------------
+# Setting assembler data.
+#------------------------------------------------------------------------------
+%.$(OBJ): %.s
+	cpp $(ASM_FLAGS) <$< | grep -v '^#' >$*.tmp
+	$(ASM) -o $@ $*.tmp
+	rm $*.tmp
+
+ASSEMBLY_SOURCE=$(arch)-gas
+ifeq (itanium,$(arch))
+    ASM=ias
+    TBB_ASM.OBJ = atomic_support.o lock_byte.o log2.o pause.o
+endif 
+#------------------------------------------------------------------------------
+# End of setting assembler data.
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# Setting tbbmalloc data.
+#------------------------------------------------------------------------------
+M_INCLUDES = $(INCLUDES) -I$(MALLOC_ROOT) -I$(MALLOC_SOURCE_ROOT)
+M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions -fno-schedule-insns2
+#------------------------------------------------------------------------------
+# End of setting tbbmalloc data.
+#------------------------------------------------------------------------------
diff -r 627751b671bb -r ac2c116b7cee build/freebsd.inc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build/freebsd.inc	Sat Sep 29 16:51:17 2007 -0700
@@ -0,0 +1,86 @@
+# Copyright 2005-2007 Intel Corporation.  All Rights Reserved.
+#
+# This file is part of Threading Building Blocks.
+#
+# Threading Building Blocks is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation.
+#
+# Threading Building Blocks is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Threading Building Blocks; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# As a special exception, you may use this file as part of a free software
+# library without restriction.  Specifically, if other files instantiate
+# templates or use macros or inline functions from this file, or you compile
+# this file and link it with other files to produce an executable, this
+# file does not by itself cause the resulting executable to be covered by
+# the GNU General Public License.  This exception does not however
+# invalidate any other reasons why the executable file might be covered by
+# the GNU General Public License.
+
+ifndef arch
+        ifeq ($(shell uname -m),i686)
+                export arch:=ia32
+        endif
+        ifeq ($(shell uname -m),ia64)
+                export arch:=itanium
+        endif
+        ifeq ($(shell uname -m),amd64)
+                export arch:=em64t
+        endif
+endif
+
+ifndef runtime
+        gcc_version_full=$(shell gcc --version | grep 'gcc'| egrep -o ' [0-9]+\.[0-9]+\.[0-9]+.*' | sed -e 's/^\ //')
+        gcc_version=$(shell echo "$(gcc_version_full)" | egrep -o '^[0-9]+\.[0-9]+\.[0-9]+\s*' | head -n 1 | sed -e 's/ *//g')
+        os_version:=$(shell uname -r)
+        os_kernel_version:=$(shell uname -r | sed -e 's/-.*$$//')
+        export runtime:=cc$(os_version)
+endif
+
+native_compiler := gcc
+export compiler ?= gcc
+debugger ?= gdb
+
+CWD=$(shell pwd)
+RM?=rm -f
+RD?=rmdir
+MD?=mkdir -p
+NUL= > /dev/null 2>&1
+SLASH=/
+MAKE_VERSIONS=sh $(tbb_root)/build/version_info_linux.sh $(CPLUS) $(CPLUS_FLAGS) $(INCLUDES) >version_string.tmp
+MAKE_TBBVARS=sh $(tbb_root)/build/generate_tbbvars.sh
+
+ifdef LD_LIBRARY_PATH
+        export LD_LIBRARY_PATH := .:$(LD_LIBRARY_PATH)
+else
+        export LD_LIBRARY_PATH := .
+endif
+
+####### Build settigns ########################################################
+
+OBJ = o
+DLL = so
+LIBEXT = so
+
+ifeq ($(cfg),debug)
+    DEBUG_SUFFIX = _debug
+endif
+
+TBB.DEF = 
+TBB.DLL = libtbb$(DEBUG_SUFFIX).$(DLL)
+TBB.LIB = $(TBB.DLL)
+
+MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).so
+MALLOC.LIB = $(MALLOC.DLL)
+
+TBB_NOSTRICT=1
+
+
+
diff -r 627751b671bb -r ac2c116b7cee examples/common/gui/convideo.cpp
--- a/examples/common/gui/convideo.cpp	Sat Sep 29 16:18:03 2007 -0700
+++ b/examples/common/gui/convideo.cpp	Sat Sep 29 16:51:17 2007 -0700
@@ -48,7 +48,7 @@ void video::win_load_accelerators(int id
 }
 #endif
 
-#elif __linux__ || __APPLE__
+#elif __linux__ || __APPLE__ || __FreeBSD__
 
 #include <sched.h>
 #include <sys/time.h>
diff -r 627751b671bb -r ac2c116b7cee examples/parallel_for/tacheon/src/types.h
--- a/examples/parallel_for/tacheon/src/types.h	Sat Sep 29 16:18:03 2007 -0700
+++ b/examples/parallel_for/tacheon/src/types.h	Sat Sep 29 16:51:17 2007 -0700
@@ -61,6 +61,8 @@
 #ifdef _WIN32
 #include <malloc.h>
 #define alloca _alloca
+#elif __FreeBSD__
+#include <stdlib.h>
 #else
 #include <alloca.h>
 #endif
diff -r 627751b671bb -r ac2c116b7cee examples/parallel_reduce/convex_hull/convex_hull.h
--- a/examples/parallel_reduce/convex_hull/convex_hull.h	Sat Sep 29 16:18:03 2007 -0700
+++ b/examples/parallel_reduce/convex_hull/convex_hull.h	Sat Sep 29 16:51:17 2007 -0700
@@ -133,7 +133,7 @@ namespace util {
     };
 
     int random(unsigned int& rseed) {
-#if __linux__ || __APPLE__
+#if __linux__ || __APPLE__ || __FreeBSD__
             return rand_r(&rseed);
 #elif _WIN32
             return rand();
diff -r 627751b671bb -r ac2c116b7cee include/tbb/machine/freebsd_em64t.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/tbb/machine/freebsd_em64t.h	Sat Sep 29 16:51:17 2007 -0700
@@ -0,0 +1,160 @@
+/*
+    Copyright 2005-2007 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks.
+
+    Threading Building Blocks is free software; you can redistribute it
+    and/or modify it under the terms of the GNU General Public License
+    version 2 as published by the Free Software Foundation.
+
+    Threading Building Blocks is distributed in the hope that it will be
+    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Threading Building Blocks; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    As a special exception, you may use this file as part of a free software
+    library without restriction.  Specifically, if other files instantiate
+    templates or use macros or inline functions from this file, or you compile
+    this file and link it with other files to produce an executable, this
+    file does not by itself cause the resulting executable to be covered by
+    the GNU General Public License.  This exception does not however
+    invalidate any other reasons why the executable file might be covered by
+    the GNU General Public License.
+*/
+
+#ifndef __TBB_machine_H
+#error Do not include this file directly; include tbb_machine.h instead
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+#include <sched.h>
+
+#define __TBB_OFFSET_OF_NEXT -8
+#define __TBB_WORDSIZE 8
+#define __TBB_BIG_ENDIAN 0
+
+//! Load with acquire semantics, both for hardware and compiler.
+template<typename T>
+inline T __TBB_load_with_acquire_via_explicit_fence(const volatile T& location) {
+    T tmp = location;
+    __asm__ __volatile__("": : :"memory");
+    return tmp;
+}
+
+//! Store with release semantics, both for hardware and compiler.
+template<typename T, typename V>
+inline void __TBB_store_with_release_via_explicit_fence(volatile T& location, V value) {
+    __asm__ __volatile__("": : :"memory");
+    location = value;
+}
+
+#define __TBB_load_with_acquire __TBB_load_with_acquire_via_explicit_fence
+#define __TBB_store_with_release __TBB_store_with_release_via_explicit_fence
+
+#define __MACHINE_DECL_ATOMICS(S,T,X) \
+static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand )         \
+{                                                                                    \
+    T result;                                                                        \
+                                                                                     \
+    __asm__ __volatile__("lock\ncmpxchg" X " %2,%1"                                       \
+                          : "=a"(result), "=m"(*(T *)ptr)                                             \
+                          : "q"(value), "0"(comparand)               \
+                          : "memory");                                               \
+    return result;                                                                   \
+}                                                                                    \
+                                                                                     \
+static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend)                     \
+{                                                                                    \
+    T result;                                                                        \
+    __asm__ __volatile__("lock\nxadd" X " %0,%1"                                          \
+                          : "=r"(result),"=m"(*(T *)ptr)                                             \
+                          : "0"(addend)                              \
+                          : "memory");                                               \
+    return result;                                                                   \
+}                                                                                    \
+                                                                                     \
+static inline  T __TBB_machine_fetchstore##S(volatile void *ptr, T value)                   \
+{                                                                                    \
+    T result;                                                                        \
+    __asm__ __volatile__("lock\nxchg" X " %0,%1"                                          \
+                          : "=r"(result),"=m"(*(T *)ptr)                                             \
+                          : "0"(value)                               \
+                          : "memory");                                               \
+    return result;                                                                   \
+}                                                                                    \
+                                                                                     
+__MACHINE_DECL_ATOMICS(1,int8_t,"")
+__MACHINE_DECL_ATOMICS(2,int16_t,"")
+__MACHINE_DECL_ATOMICS(4,int32_t,"")
+__MACHINE_DECL_ATOMICS(8,int64_t,"q")
+
+static inline int64_t __TBB_machine_lg( uint64_t x ) {
+    int64_t j;
+    __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x));
+    return j;
+}
+
+static inline void __TBB_machine_or( volatile void *ptr, uint64_t addend ) {
+    __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(uint64_t *)ptr) : "r"(addend) : "memory");
+}
+
+static inline void __TBB_machine_pause( int32_t delay ) {
+    for (int32_t i = 0; i < delay; i++) {
+       __asm__ __volatile__("pause;");
+    }
+    return;
+}   
+
+// Machine specific atomic operations
+
+#define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C)
+#define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C)
+#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
+#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
+#define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C)
+
+#define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V)
+#define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V)
+#define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4(P,V)
+#define __TBB_FetchAndAdd8(P,V)  __TBB_machine_fetchadd8(P,V)
+#define __TBB_FetchAndAddW(P,V)  __TBB_machine_fetchadd8(P,V)
+
+#define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V)
+#define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V)
+#define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4(P,V)
+#define __TBB_FetchAndStore8(P,V)  __TBB_machine_fetchstore8(P,V)
+#define __TBB_FetchAndStoreW(P,V)  __TBB_machine_fetchstore8(P,V)
+
+#define __TBB_Store8(P,V) (*P = V)
+#define __TBB_Load8(P)    (*P)
+
+#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V)
+
+// Definition of other functions
+#define __TBB_Yield()  sched_yield()
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+#define __TBB_Log2(V)    __TBB_machine_lg(V)
+
+// Special atomic functions
+#define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V)
+#define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1)
+#define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,-1)
+
+// Definition of Lock functions
+#undef __TBB_TryLockByte
+#undef __TBB_LockByte
+
+#define __TBB_cpuid
+static inline void __TBB_x86_cpuid( int32_t buffer[4], int32_t mode ) {
+    // NOTE: gcc sometimes fails to compile the following asm.  But icc always succeeds.
+    __asm__ ("cpuid" : "=a"(buffer[0]),
+                       "=b"(buffer[1]),
+                       "=c"(buffer[2]),
+                       "=d"(buffer[3]) : "0"(mode) : "memory" );
+}
+
diff -r 627751b671bb -r ac2c116b7cee include/tbb/machine/freebsd_ia32.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/tbb/machine/freebsd_ia32.h	Sat Sep 29 16:51:17 2007 -0700
@@ -0,0 +1,225 @@
+/*
+    Copyright 2005-2007 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks.
+
+    Threading Building Blocks is free software; you can redistribute it
+    and/or modify it under the terms of the GNU General Public License
+    version 2 as published by the Free Software Foundation.
+
+    Threading Building Blocks is distributed in the hope that it will be
+    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Threading Building Blocks; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    As a special exception, you may use this file as part of a free software
+    library without restriction.  Specifically, if other files instantiate
+    templates or use macros or inline functions from this file, or you compile
+    this file and link it with other files to produce an executable, this
+    file does not by itself cause the resulting executable to be covered by
+    the GNU General Public License.  This exception does not however
+    invalidate any other reasons why the executable file might be covered by
+    the GNU General Public License.
+*/
+
+#ifndef __TBB_machine_H
+#error Do not include this file directly; include tbb_machine.h instead
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+#include <sched.h>
+
+#define __TBB_OFFSET_OF_NEXT -4
+#define __TBB_WORDSIZE 4
+#define __TBB_BIG_ENDIAN 0
+
+
+#define __MACHINE_DECL_ATOMICS(S,T,X) \
+static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand )         \
+{                                                                                    \
+    T result;                                                                        \
+                                                                                     \
+    __asm__ __volatile__("lock\ncmpxchg" X " %2,%1"                                       \
+                          : "=a"(result), "=m"(*(T *)ptr)                                             \
+                          : "q"(value), "0"(comparand)               \
+                          : "memory");                                               \
+    return result;                                                                   \
+}                                                                                    \
+                                                                                     \
+static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend)                     \
+{                                                                                    \
+    T result;                                                                        \
+    __asm__ __volatile__("lock\nxadd" X " %0,%1"                                          \
+                          : "=r"(result), "=m"(*(T *)ptr)                                             \
+                          : "0"(addend)                              \
+                          : "memory");                                               \
+   return result;                                                                    \
+}                                                                                    \
+                                                                                     \
+static inline  T __TBB_machine_fetchstore##S(volatile void *ptr, T value)                   \
+{                                                                                    \
+    T result;                                                                        \
+    __asm__ __volatile__("lock\nxchg" X " %0,%1"                                          \
+                          : "=r"(result), "=m"(*(T *)ptr)                                             \
+                          : "0"(value)                               \
+                          : "memory");                                               \
+   return result;                                                                    \
+}                                                                                    \
+                                                                                     
+__MACHINE_DECL_ATOMICS(1,int8_t,"")
+__MACHINE_DECL_ATOMICS(2,int16_t,"")
+__MACHINE_DECL_ATOMICS(4,int32_t,"l")
+
+static int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand )
+{
+    const int32_t comparand_lo = (int32_t)comparand;
+    const int32_t comparand_hi = *(int32_t*)((intptr_t)&comparand+sizeof(int32_t));
+    int64_t result;
+    // EBX register saved for compliancy with position-independent code (PIC) rules on IA32
+    __asm__ __volatile__ (
+             "pushl %%ebx\n\t"
+             "movl  (%%ecx),%%ebx\n\t"
+             "movl  4(%%ecx),%%ecx\n\t"
+             "lock\ncmpxchg8b (%2)\n\t"
+             "popl  %%ebx"
+                    : "=A"(result), "=m"(*(int64_t *)ptr)
+                    : "S"(ptr),
+                      "a"(comparand_lo),
+                      "d"(comparand_hi),
+                      "c"(&value)
+                    : "memory", "esp");
+    return result;
+}
+
+static inline int32_t __TBB_machine_lg( uint32_t x ) {
+    int32_t j;
+    __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x));
+    return j;
+}
+
+static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) {
+    __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(uint32_t *)ptr) : "r"(addend) : "memory");
+}
+
+static inline void __TBB_machine_pause( int32_t delay ) {
+    for (int32_t i = 0; i < delay; i++) {
+       __asm__ __volatile__("pause;");
+    }
+    return;
+}   
+
+static inline int64_t __TBB_machine_load8 (const volatile void *ptr) {
+    int64_t result;
+    __asm__ __volatile__ ( "fildq %1\n\t"
+                           "fistpq %0" :  "=m"(result) : "m"(*(uint64_t *)ptr), "m"(result) : "memory" );
+    return result;
+}
+
+static inline void __TBB_machine_store8 (volatile void *ptr, int64_t value) {
+    __asm__ __volatile__ ( "fildq %1\n\t"
+                           "fistpq (%2)" :  "=m"(*(int64_t *)ptr) : "m"(value), "r"(ptr) : "memory" );
+}
+
+template <typename T, size_t S>
+struct __TBB_machine_load_store {
+    static inline T load_with_acquire(const volatile T& location) {
+        T to_return = location;
+        __asm__ __volatile__("" : : : "memory" );   // Compiler fence to keep operations from migrating upwards
+        return to_return;
+    }
+
+    static inline void store_with_release(volatile T &location, T value) {
+        __asm__ __volatile__("" : : : "memory" );   // Compiler fence to keep operations from migrating upwards
+        location = value;
+    }
+};
+
+template <typename T>
+struct __TBB_machine_load_store<T,8> {
+    static inline T load_with_acquire(const volatile T& location) {
+        T to_return = __TBB_machine_load8((volatile void *)&location);
+        __asm__ __volatile__("" : : : "memory" );   // Compiler fence to keep operations from migrating upwards
+        return to_return;
+    }
+
+    static inline void store_with_release(volatile T &location, T value) {
+        __asm__ __volatile__("" : : : "memory" );   // Compiler fence to keep operations from migrating downwards
+        __TBB_machine_store8((volatile void *)&location,(int64_t)value);
+    }
+};
+
+template<typename T>
+inline T __TBB_machine_load_with_acquire(const volatile T &location) {
+    return __TBB_machine_load_store<T,sizeof(T)>::load_with_acquire(location);
+}
+
+template<typename T, typename V>
+inline void __TBB_machine_store_with_release(volatile T &location, V value) {
+    __TBB_machine_load_store<T,sizeof(T)>::store_with_release(location,value);
+}
+
+#define __TBB_load_with_acquire(L) __TBB_machine_load_with_acquire((L))
+#define __TBB_store_with_release(L,V) __TBB_machine_store_with_release((L),(V))
+
+// Machine specific atomic operations
+
+#define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1(P,V,C)
+#define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2(P,V,C)
+#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
+#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
+#define __TBB_CompareAndSwapW(P,V,C)  __TBB_machine_cmpswp4(P,V,C)
+
+#define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1(P,V)
+#define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2(P,V)
+#define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4(P,V)
+#define __TBB_FetchAndAddW(P,V)  __TBB_machine_fetchadd4(P,V)
+
+#define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1(P,V)
+#define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2(P,V)
+#define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4(P,V)
+#define __TBB_FetchAndStoreW(P,V)  __TBB_machine_fetchstore4(P,V)
+
+#define __TBB_Store8(P,V) __TBB_machine_store8(P,V)
+#define __TBB_Load8(P)    __TBB_machine_load8(P)
+
+#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V)
+
+
+// Those we chose not to implement (they will be implemented generically using CMPSWP8)
+#undef __TBB_FetchAndAdd8
+#undef __TBB_FetchAndStore8
+
+// Definition of other functions
+#define __TBB_Yield()  sched_yield()
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+#define __TBB_Log2(V)    __TBB_machine_lg(V)
+
+// Special atomic functions
+#define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V)
+#define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1)
+#define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,-1)
+
+// Definition of Lock functions
+#undef __TBB_TryLockByte
+#undef __TBB_LockByte
+
+#define __TBB_cpuid
+static inline void __TBB_x86_cpuid( int32_t buffer[4], int32_t mode ) {
+    // EBX register saved for compliancy with position-independent code (PIC) rules on IA32
+    __asm__ ("pushl %%ebx\n\t"
+             "cpuid\n\t"
+             "movl  %%ebx,%1\n\t"
+             "popl  %%ebx"
+                    : "=a"(buffer[0]),
+                      "=S"(buffer[1]),
+                      "=c"(buffer[2]),
+                      "=d"(buffer[3])
+                    : "0"(mode)
+                    : "memory" );
+}
+
diff -r 627751b671bb -r ac2c116b7cee include/tbb/machine/freebsd_itanium.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/tbb/machine/freebsd_itanium.h	Sat Sep 29 16:51:17 2007 -0700
@@ -0,0 +1,179 @@
+/*
+    Copyright 2005-2007 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks.
+
+    Threading Building Blocks is free software; you can redistribute it
+    and/or modify it under the terms of the GNU General Public License
+    version 2 as published by the Free Software Foundation.
+
+    Threading Building Blocks is distributed in the hope that it will be
+    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Threading Building Blocks; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    As a special exception, you may use this file as part of a free software
+    library without restriction.  Specifically, if other files instantiate
+    templates or use macros or inline functions from this file, or you compile
+    this file and link it with other files to produce an executable, this
+    file does not by itself cause the resulting executable to be covered by
+    the GNU General Public License.  This exception does not however
+    invalidate any other reasons why the executable file might be covered by
+    the GNU General Public License.
+*/
+
+#ifndef __TBB_machine_H
+#error Do not include this file directly; include tbb_machine.h instead
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+#include <sched.h>
+#include <ia64intrin.h>
+
+#define __TBB_OFFSET_OF_NEXT -8
+#define __TBB_WORDSIZE 8
+#define __TBB_BIG_ENDIAN 0
+#define __TBB_DECL_FENCED_ATOMICS 1
+
+// Most of the functions will be in a .s file
+
+extern "C" {
+    int8_t __TBB_machine_cmpswp1__TBB_full_fence (volatile void *ptr, int8_t value, int8_t comparand); 
+    int8_t __TBB_machine_fetchadd1__TBB_full_fence (volatile void *ptr, int8_t addend);
+    int8_t __TBB_machine_fetchadd1acquire(volatile void *ptr, int8_t addend);
+    int8_t __TBB_machine_fetchadd1release(volatile void *ptr, int8_t addend);
+    int8_t __TBB_machine_fetchstore1acquire(volatile void *ptr, int8_t value);
+    int8_t __TBB_machine_fetchstore1release(volatile void *ptr, int8_t value);
+
+    int16_t __TBB_machine_cmpswp2__TBB_full_fence (volatile void *ptr, int16_t value, int16_t comparand);
+    int16_t __TBB_machine_fetchadd2__TBB_full_fence (volatile void *ptr, int16_t addend);
+    int16_t __TBB_machine_fetchadd2acquire(volatile void *ptr, int16_t addend);
+    int16_t __TBB_machine_fetchadd2release(volatile void *ptr, int16_t addend);
+    int16_t __TBB_machine_fetchstore2acquire(volatile void *ptr, int16_t value);
+    int16_t __TBB_machine_fetchstore2release(volatile void *ptr, int16_t value);
+
+    int32_t __TBB_machine_fetchstore4__TBB_full_fence (volatile void *ptr, int32_t value);
+    int32_t __TBB_machine_fetchstore4acquire(volatile void *ptr, int32_t value);
+    int32_t __TBB_machine_fetchstore4release(volatile void *ptr, int32_t value);
+    int32_t __TBB_machine_fetchadd4acquire(volatile void *ptr, int32_t addend);
+    int32_t __TBB_machine_fetchadd4release(volatile void *ptr, int32_t addend);
+
+    int64_t __TBB_machine_cmpswp8__TBB_full_fence (volatile void *ptr, int64_t value, int64_t comparand);
+    int64_t __TBB_machine_fetchstore8__TBB_full_fence (volatile void *ptr, int64_t value);
+    int64_t __TBB_machine_fetchstore8acquire(volatile void *ptr, int64_t value);
+    int64_t __TBB_machine_fetchstore8release(volatile void *ptr, int64_t value);
+    int64_t __TBB_machine_fetchadd8acquire(volatile void *ptr, int64_t addend);
+    int64_t __TBB_machine_fetchadd8release(volatile void *ptr, int64_t addend);
+
+    int8_t __TBB_machine_cmpswp1acquire(volatile void *ptr, int8_t value, int8_t comparand); 
+    int8_t __TBB_machine_cmpswp1release(volatile void *ptr, int8_t value, int8_t comparand); 
+    int8_t __TBB_machine_fetchstore1__TBB_full_fence (volatile void *ptr, int8_t value);
+
+    int16_t __TBB_machine_cmpswp2acquire(volatile void *ptr, int16_t value, int16_t comparand); 
+    int16_t __TBB_machine_cmpswp2release(volatile void *ptr, int16_t value, int16_t comparand); 
+    int16_t __TBB_machine_fetchstore2__TBB_full_fence (volatile void *ptr, int16_t value);
+
+    int32_t __TBB_machine_cmpswp4__TBB_full_fence (volatile void *ptr, int32_t value, int32_t comparand);
+    int32_t __TBB_machine_cmpswp4acquire(volatile void *ptr, int32_t value, int32_t comparand); 
+    int32_t __TBB_machine_cmpswp4release(volatile void *ptr, int32_t value, int32_t comparand); 
+    int32_t __TBB_machine_fetchadd4__TBB_full_fence (volatile void *ptr, int32_t value);
+
+    int64_t __TBB_machine_cmpswp8acquire(volatile void *ptr, int64_t value, int64_t comparand); 
+    int64_t __TBB_machine_cmpswp8release(volatile void *ptr, int64_t value, int64_t comparand); 
+    int64_t __TBB_machine_fetchadd8__TBB_full_fence (volatile void *ptr, int64_t value);
+
+    int64_t __TBB_machine_lg(uint64_t value);
+    void __TBB_machine_pause(int32_t delay);
+    bool __TBB_machine_trylockbyte( volatile unsigned char &ptr );
+}
+
+#define __TBB_CompareAndSwap1(P,V,C) __TBB_machine_cmpswp1__TBB_full_fence(P,V,C)
+#define __TBB_CompareAndSwap2(P,V,C) __TBB_machine_cmpswp2__TBB_full_fence(P,V,C) 
+
+#define __TBB_FetchAndAdd1(P,V) __TBB_machine_fetchadd1__TBB_full_fence(P,V)
+#define __TBB_FetchAndAdd1acquire(P,V) __TBB_machine_fetchadd1acquire(P,V)
+#define __TBB_FetchAndAdd1release(P,V) __TBB_machine_fetchadd1release(P,V)
+#define __TBB_FetchAndAdd2(P,V) __TBB_machine_fetchadd2__TBB_full_fence(P,V)
+#define __TBB_FetchAndAdd2acquire(P,V) __TBB_machine_fetchadd2acquire(P,V)
+#define __TBB_FetchAndAdd2release(P,V) __TBB_machine_fetchadd2release(P,V)
+#define __TBB_FetchAndAdd4acquire(P,V) __TBB_machine_fetchadd4acquire(P,V)
+#define __TBB_FetchAndAdd4release(P,V) __TBB_machine_fetchadd4release(P,V)
+#define __TBB_FetchAndAdd8acquire(P,V) __TBB_machine_fetchadd8acquire(P,V)
+#define __TBB_FetchAndAdd8release(P,V) __TBB_machine_fetchadd8release(P,V)
+
+#define __TBB_FetchAndStore1acquire(P,V) __TBB_machine_fetchstore1acquire(P,V)
+#define __TBB_FetchAndStore1release(P,V) __TBB_machine_fetchstore1release(P,V)
+#define __TBB_FetchAndStore2acquire(P,V) __TBB_machine_fetchstore2acquire(P,V)
+#define __TBB_FetchAndStore2release(P,V) __TBB_machine_fetchstore2release(P,V)
+#define __TBB_FetchAndStore4acquire(P,V) __TBB_machine_fetchstore4acquire(P,V)
+#define __TBB_FetchAndStore4release(P,V) __TBB_machine_fetchstore4release(P,V)
+#define __TBB_FetchAndStore8acquire(P,V) __TBB_machine_fetchstore8acquire(P,V)
+#define __TBB_FetchAndStore8release(P,V) __TBB_machine_fetchstore8release(P,V)
+
+#define __TBB_CompareAndSwap1acquire(P,V,C) __TBB_machine_cmpswp1acquire(P,V,C)
+#define __TBB_CompareAndSwap1release(P,V,C) __TBB_machine_cmpswp1release(P,V,C)
+#define __TBB_CompareAndSwap2acquire(P,V,C) __TBB_machine_cmpswp2acquire(P,V,C)
+#define __TBB_CompareAndSwap2release(P,V,C) __TBB_machine_cmpswp2release(P,V,C)
+#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4__TBB_full_fence(P,V,C)
+#define __TBB_CompareAndSwap4acquire(P,V,C) __TBB_machine_cmpswp4acquire(P,V,C)
+#define __TBB_CompareAndSwap4release(P,V,C) __TBB_machine_cmpswp4release(P,V,C)
+#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8__TBB_full_fence(P,V,C)
+#define __TBB_CompareAndSwap8acquire(P,V,C) __TBB_machine_cmpswp8acquire(P,V,C)
+#define __TBB_CompareAndSwap8release(P,V,C) __TBB_machine_cmpswp8release(P,V,C)
+
+#define __TBB_FetchAndAdd4(P,V) __TBB_machine_fetchadd4__TBB_full_fence(P,V)
+#define __TBB_FetchAndAdd8(P,V) __TBB_machine_fetchadd8__TBB_full_fence(P,V)
+
+#define __TBB_FetchAndStore1(P,V) __TBB_machine_fetchstore1__TBB_full_fence(P,V)
+#define __TBB_FetchAndStore2(P,V) __TBB_machine_fetchstore2__TBB_full_fence(P,V)
+#define __TBB_FetchAndStore4(P,V) __TBB_machine_fetchstore4__TBB_full_fence(P,V)
+#define __TBB_FetchAndStore8(P,V) __TBB_machine_fetchstore8__TBB_full_fence(P,V)
+
+#define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAdd8acquire(P,1)
+#define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAdd8release(P,-1)
+
+#ifndef __INTEL_COMPILER
+template<typename T, typename V>
+inline void __TBB_store_with_release_via_explicit_fence(volatile T& location, V value) {
+    __asm__ __volatile__("": : :"memory");
+    location = value;
+}
+
+//! Load with acquire semantics, both for hardware and compiler.
+/** Even though GCC imbues volatile loads with acquire semantics, 
+    it sometimes hoists loads over the acquire fence.  We use
+    an explicit memory fence to prevent such incorrect hoisting. */
+template<typename T>
+inline T __TBB_load_with_acquire_via_explicit_fence(const volatile T& location) {
+    T tmp = location;
+    __asm__ __volatile__("": : :"memory");
+    return tmp;
+}
+#define __TBB_load_with_acquire(L) __TBB_load_with_acquire_via_explicit_fence(L)
+#define __TBB_store_with_release(L,V) __TBB_store_with_release_via_explicit_fence(L,V)
+#endif
+
+// Special atomic functions
+#define __TBB_CompareAndSwapW(P,V,C) __TBB_CompareAndSwap8(P,V,C)
+#define __TBB_FetchAndStoreW(P,V) __TBB_FetchAndStore8(P,V)
+#define __TBB_FetchAndAddW(P,V) __TBB_FetchAndAdd8(P,V)
+#define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAdd8release(P,V)
+
+// Not needed
+#undef __TBB_Store8
+#undef __TBB_Load8
+
+// Definition of Lock functions
+#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P)  
+#undef  __TBB_LockByte
+
+// Definition of other utility functions
+#define __TBB_Yield()  sched_yield()
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+#define __TBB_Log2(V)    __TBB_machine_lg(V)
+
diff -r 627751b671bb -r ac2c116b7cee include/tbb/tbb_machine.h
--- a/include/tbb/tbb_machine.h	Sat Sep 29 16:18:03 2007 -0700
+++ b/include/tbb/tbb_machine.h	Sat Sep 29 16:51:17 2007 -0700
@@ -65,6 +65,16 @@ typedef unsigned __int64 uint64_t;
 #include "tbb/machine/linux_em64t.h"
 #elif __ia64__
 #include "tbb/machine/linux_itanium.h"
+#endif
+
+#elif __FreeBSD__
+
+#if __i386__
+#include "tbb/machine/freebsd_ia32.h"
+#elif __x86_64__
+#include "tbb/machine/freebsd_em64t.h"
+#elif __ia64__
+#include "tbb/machine/freebsd_itanium.h"
 #endif
 
 #elif __APPLE__
diff -r 627751b671bb -r ac2c116b7cee src/tbb/cache_aligned_allocator.cpp
--- a/src/tbb/cache_aligned_allocator.cpp	Sat Sep 29 16:18:03 2007 -0700
+++ b/src/tbb/cache_aligned_allocator.cpp	Sat Sep 29 16:51:17 2007 -0700
@@ -69,7 +69,7 @@ static const DynamicLinkDescriptor Mallo
 #define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll"
 #elif __APPLE__
 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".dylib"
-#elif __linux__
+#elif __linux__ || __FreeBSD__
 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so"
 #else
 #error Unknown OS
diff -r 627751b671bb -r ac2c116b7cee src/tbb/itt_notify.cpp
--- a/src/tbb/itt_notify.cpp	Sat Sep 29 16:18:03 2007 -0700
+++ b/src/tbb/itt_notify.cpp	Sat Sep 29 16:51:17 2007 -0700
@@ -70,7 +70,7 @@ static const DynamicLinkDescriptor ITT_H
 // LIBITTNOTIFY_NAME is the name of the ITT notification library 
 # if _WIN32||_WIN64
 #  define LIBITTNOTIFY_NAME "libittnotify.dll"
-# elif __linux__
+# elif __linux__ || __FreeBSD__
 #  define LIBITTNOTIFY_NAME "libittnotify.so"
 # elif __APPLE__
 #  define LIBITTNOTIFY_NAME "libittnotify.dylib"
diff -r 627751b671bb -r ac2c116b7cee src/tbb/tbb_misc.h
--- a/src/tbb/tbb_misc.h	Sat Sep 29 16:18:03 2007 -0700
+++ b/src/tbb/tbb_misc.h	Sat Sep 29 16:51:17 2007 -0700
@@ -32,11 +32,8 @@
 #include "tbb/tbb_stddef.h"
 #include "tbb/tbb_machine.h"
 
-#if __linux__
-#include <sys/sysinfo.h>
-#elif __APPLE__
-#include <sys/types.h>
-#include <sys/sysctl.h>
+#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
+#include <unistd.h>
 #endif
 
 namespace tbb {
@@ -59,24 +56,11 @@ static inline int DetectNumberOfWorkers(
     return number_of_workers; 
 }
 
-#elif __linux__ 
+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
 
 static inline int DetectNumberOfWorkers( void ) {
     if (!number_of_workers) {
-        number_of_workers = get_nprocs();
-    }
-    return number_of_workers; 
-}
-
-#elif __APPLE__
-
-static inline int DetectNumberOfWorkers( void ) {
-    if (!number_of_workers) {
-        int name[2] = {CTL_HW, HW_AVAILCPU};
-        int ncpu;
-        size_t size = sizeof(ncpu);
-        sysctl( name, 2, &ncpu, &size, NULL, 0 );
-        number_of_workers = ncpu;
+        number_of_workers = sysconf(_SC_NPROCESSORS_ONLN);
     }
     return number_of_workers; 
 }
diff -r 627751b671bb -r ac2c116b7cee src/tbbmalloc/MemoryAllocator.cpp
--- a/src/tbbmalloc/MemoryAllocator.cpp	Sat Sep 29 16:18:03 2007 -0700
+++ b/src/tbbmalloc/MemoryAllocator.cpp	Sat Sep 29 16:51:17 2007 -0700
@@ -324,7 +324,7 @@ static inline unsigned int highestBitPos
     unsigned int pos;
 #if __ARCH_x86_32||__ARCH_x86_64
 
-# if __linux__||__APPLE__
+# if __linux__||__APPLE__ || __FreeBSD__
     __asm__ ("bsr %1,%0" : "=r"(pos) : "r"(number));
 # elif (_WIN32 && (!_WIN64 || __INTEL_COMPILER))
     __asm
diff -r 627751b671bb -r ac2c116b7cee src/test/harness.h
--- a/src/test/harness.h	Sat Sep 29 16:18:03 2007 -0700
+++ b/src/test/harness.h	Sat Sep 29 16:51:17 2007 -0700
@@ -38,7 +38,7 @@
 #include "tbb/tbb_stddef.h"
 #include "harness_assert.h"
 
-#if __linux__||__APPLE__
+#if __linux__||__APPLE__ || __FreeBSD__
     #include <pthread.h>
 #elif _WIN32||WIN64
     #include <windows.h>
@@ -120,7 +120,7 @@ public:
 
     //! Start task
     void start() {
-#if __linux__||__APPLE__
+#if __linux__||__APPLE__ || __FreeBSD__
         int status = pthread_create(&thread_id, NULL, thread_function, this);
         ASSERT(0==status, "NativeParallelFor: pthread_create failed");
 #else
@@ -132,7 +132,7 @@ public:
 
     //! Wait for task to finish
     void wait_to_finish() {
-#if __linux__||__APPLE__
+#if __linux__||__APPLE__ || __FreeBSD__
         int status = pthread_join( thread_id, NULL );
         ASSERT( !status, "pthread_join failed" );
 #else
@@ -148,7 +148,7 @@ public:
         Top-level caller should let index default to 0. */
     static size_t build_task_array( const Range& range, const Body& body, NativeParalleForTask* array, size_t index ); 
 private:
-#if __linux__||__APPLE__
+#if __linux__||__APPLE__ || __FreeBSD__
     pthread_t thread_id;
 #else
     HANDLE thread_handle;
@@ -160,7 +160,7 @@ private:
     //! Body to invoke over the range.
     const Body body;
 
-#if __linux__||__APPLE__
+#if __linux__||__APPLE__ || __FreeBSD__
     static void* thread_function(void* object)
 #else
     static unsigned __stdcall thread_function( void* object )
--- a/src/test/test_concurrent_hash_map.cpp	Sat Sep 29 16:51:17 2007 -0700
+++ b/src/test/test_concurrent_hash_map.cpp	Sat Sep 29 17:08:18 2007 -0700
@@ -320,7 +320,7 @@ public:
                     // more logical threads than physical threads, and should yield in 
                     // order to let suspended logical threads make progress.
                     j = 0;
-#if __linux__||__APPLE__
+#if __linux__ || __APPLE__ || __FreeBSD__
                     sched_yield();
 #else
                     Sleep(0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070929151437.GA35489>