From 200fbe924466720bd2a8c5eb05b05d67b0a2414c Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 14 Mar 2013 15:42:19 +0100 Subject: Added support for ENEA OSE This port has support for both non-smp and smp. It contains a new way to do io checking in which erts_poll_wait receives the payload of the polled entity. This has implications for all linked-in drivers. --- erts/include/internal/ethr_mutex.h | 22 +++++++ erts/include/internal/ethread.h | 97 +++++++++++++++++++++++++++++- erts/include/internal/ose/ethr_event.h | 104 +++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 erts/include/internal/ose/ethr_event.h (limited to 'erts/include') diff --git a/erts/include/internal/ethr_mutex.h b/erts/include/internal/ethr_mutex.h index 86a1e9fbdf..9511add075 100644 --- a/erts/include/internal/ethr_mutex.h +++ b/erts/include/internal/ethr_mutex.h @@ -103,6 +103,9 @@ void LeaveCriticalSection(CRITICAL_SECTION *); #elif defined(ETHR_WIN32_THREADS) # define ETHR_MTX_Q_LOCK_CRITICAL_SECTION__ # define ETHR_MTX_QLOCK_TYPE__ CRITICAL_SECTION +#elif defined(ETHR_OSE_THREADS) +# define ETHR_MTX_Q_LOCK_PTHREAD_MUTEX__ +# define ETHR_MTX_QLOCK_TYPE__ pthread_mutex_t #else # error Need a qlock implementation #endif @@ -255,6 +258,25 @@ struct ethr_cond_ { #endif }; +#elif defined(ETHR_OSE_THREADS) + +typedef struct ethr_mutex_ ethr_mutex; +struct ethr_mutex_ { + pthread_mutex_t pt_mtx; +#if ETHR_XCHK + int initialized; +#endif +}; + +typedef struct ethr_cond_ ethr_cond; +struct ethr_cond_ { + pthread_cond_t pt_cnd; +#if ETHR_XCHK + int initialized; +#endif +}; + + #else # error "no mutex implementation" #endif diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h index 38b8e9e9b6..581eb22edb 100644 --- a/erts/include/internal/ethread.h +++ b/erts/include/internal/ethread.h @@ -37,6 +37,11 @@ # define ETHR_DEBUG #endif +#if defined(__PPC__) || defined (__POWERPC) +/* OSE compiler should be fixed! */ +#define __ppc__ +#endif + #if defined(ETHR_DEBUG) # undef ETHR_XCHK # define ETHR_XCHK 1 @@ -190,6 +195,36 @@ typedef DWORD ethr_tsd_key; #define ETHR_YIELD() (Sleep(0), 0) +#elif defined(ETHR_OSE_THREADS) + +#include "ose.h" +#undef NIL + +#if defined(ETHR_HAVE_PTHREAD_H) +#include +#endif + +typedef struct { + PROCESS id; + unsigned int tsd_key_index; + void *res; +} ethr_tid; + +struct ethr_tsd_key__ { + PROCESS id; + char key[]; +}; +typedef struct ethr_tsd_key__* ethr_tsd_key; + +#undef ETHR_HAVE_ETHR_SIG_FUNCS + +#define ETHR_USE_OWN_RWMTX_IMPL__ +#define ETHR_USE_OWN_MTX_IMPL__ +#define ETHR_HAVE_THREAD_NAMES +#define ETHR_HAVE_THREAD_NICENESS + +#define ETHR_PPC_HAVE_NO_LWSYNC + #else /* No supported thread lib found */ #ifdef ETHR_NO_SUPP_THR_LIB_NOT_FATAL @@ -367,7 +402,7 @@ extern ethr_runtime_t ethr_runtime__; #include "ethr_atomics.h" /* The atomics API */ -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(ETHR_OSE_THREADS) # ifndef ETHR_SPIN_BODY # if defined(__i386__) || defined(__x86_64__) # define ETHR_SPIN_BODY __asm__ __volatile__("rep;nop" : : : "memory") @@ -383,9 +418,20 @@ extern ethr_runtime_t ethr_runtime__; # ifndef ETHR_SPIN_BODY # define ETHR_SPIN_BODY do {YieldProcessor();ETHR_COMPILER_BARRIER;} while(0) # endif +#elif defined(ETHR_OSE_THREADS) +# ifndef ETHR_SPIN_BODY +# define ETHR_SPIN_BODY delay(1) +# else +# error "Have to use delay on OSE" +# endif #endif +#ifndef ETHR_OSE_THREADS #define ETHR_YIELD_AFTER_BUSY_LOOPS 50 +#else +#define ETHR_YIELD_AFTER_BUSY_LOOPS 0 +#endif + #ifndef ETHR_SPIN_BODY # define ETHR_SPIN_BODY ETHR_COMPILER_BARRIER @@ -408,6 +454,8 @@ extern ethr_runtime_t ethr_runtime__; # else # define ETHR_YIELD() (pthread_yield(), 0) # endif +# elif defined(ETHR_OSE_THREADS) +# define ETHR_YIELD() (delay(1), 0) # else # define ETHR_YIELD() (ethr_compiler_barrier(), 0) # endif @@ -459,9 +507,20 @@ typedef struct { typedef struct { int detached; /* boolean (default false) */ int suggested_stack_size; /* kilo words (default sys dependent) */ +#ifdef ETHR_OSE_THREADS + char *name; + OSPRIORITY prio; + U32 coreNo; +#endif } ethr_thr_opts; +#if defined(ETHR_OSE_THREADS) +/* Default ethr name is big as we want to be able to sprint stuff in there */ +#define ETHR_THR_OPTS_DEFAULT_INITER \ + {0, -1, "ethread", get_pri(current_process()), 0} +#else #define ETHR_THR_OPTS_DEFAULT_INITER {0, -1} +#endif #if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__) @@ -571,8 +630,10 @@ typedef struct ethr_ts_event_ ethr_ts_event; /* Needed by ethr_mutex.h */ #if defined(ETHR_WIN32_THREADS) # include "win/ethr_event.h" -#else +#elif defined(ETHR_PTHREADS) # include "pthread/ethr_event.h" +#elif defined(ETHR_OSE_THREADS) +# include "ose/ethr_event.h" #endif int ethr_set_main_thr_status(int, int); @@ -662,6 +723,38 @@ ETHR_INLINE_FUNC_NAME_(ethr_leave_ts_event)(ethr_ts_event *tsep) #endif +#elif defined (ETHR_OSE_THREADS) + +#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHREAD_IMPL__) + +extern char* ethr_ts_event_key__; + +static ETHR_INLINE ethr_ts_event * +ETHR_INLINE_FUNC_NAME_(ethr_get_ts_event)(void) +{ + ethr_ts_event *tsep = (ethr_ts_event *)get_envp(current_process(), + ethr_ts_event_key__); + if (!tsep) { + int res = ethr_get_tmp_ts_event__(&tsep); + if (res != 0) + ETHR_FATAL_ERROR__(res); + ETHR_ASSERT(tsep); + } + return tsep; +} + +static ETHR_INLINE void +ETHR_INLINE_FUNC_NAME_(ethr_leave_ts_event)(ethr_ts_event *tsep) +{ + if (tsep->iflgs & ETHR_TS_EV_TMP) { + int res = ethr_free_ts_event__(tsep); + if (res != 0) + ETHR_FATAL_ERROR__(res); + } +} + +#endif + #endif #include "ethr_mutex.h" /* Need atomic declarations and tse */ diff --git a/erts/include/internal/ose/ethr_event.h b/erts/include/internal/ose/ethr_event.h new file mode 100644 index 0000000000..86811a87db --- /dev/null +++ b/erts/include/internal/ose/ethr_event.h @@ -0,0 +1,104 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2009-2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/* + * Author: Rickard Green + */ + +//#define USE_PTHREAD_API + +#define ETHR_EVENT_OFF_WAITER__ -1L +#define ETHR_EVENT_OFF__ 1L +#define ETHR_EVENT_ON__ 0L + +#ifdef USE_PTHREAD_API + +typedef struct { + ethr_atomic32_t state; + pthread_mutex_t mtx; + pthread_cond_t cnd; +} ethr_event; + +#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__) + +static void ETHR_INLINE +ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e) +{ + ethr_sint32_t val; + val = ethr_atomic32_xchg_mb(&e->state, ETHR_EVENT_ON__); + if (val == ETHR_EVENT_OFF_WAITER__) { + int res = pthread_mutex_lock(&e->mtx); + if (res != 0) + ETHR_FATAL_ERROR__(res); + res = pthread_cond_signal(&e->cnd); + if (res != 0) + ETHR_FATAL_ERROR__(res); + res = pthread_mutex_unlock(&e->mtx); + if (res != 0) + ETHR_FATAL_ERROR__(res); + } +} + +static void ETHR_INLINE +ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e) +{ + ethr_atomic32_set(&e->state, ETHR_EVENT_OFF__); + ETHR_MEMORY_BARRIER; +} + +#endif + +#else + +typedef struct { + ethr_atomic32_t state; + PROCESS proc; +} ethr_event; + +#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__) + +static void ETHR_INLINE +ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e) +{ + ethr_sint32_t val = ethr_atomic32_xchg_mb(&e->state, ETHR_EVENT_ON__); + if (val == ETHR_EVENT_OFF_WAITER__) { + ETHR_ASSERT(get_fsem(e->proc) == -1); + signal_fsem(e->proc); + } +} + +static void ETHR_INLINE +ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e) +{ + ethr_atomic32_set(&e->state, ETHR_EVENT_OFF__); + ETHR_MEMORY_BARRIER; +} + +#endif + +#endif + +int ethr_event_init(ethr_event *e); +int ethr_event_destroy(ethr_event *e); +int ethr_event_wait(ethr_event *e); +int ethr_event_swait(ethr_event *e, int spincount); +#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__) +void ethr_event_set(ethr_event *e); +void ethr_event_reset(ethr_event *e); +#endif -- cgit v1.2.3