Author: mturk
Date: Sat Jun 25 07:24:33 2011
New Revision: 1139498
URL: http://svn.apache.org/viewvc?rev=1139498&view=rev
Log:
Add simple atomic support
Added:
commons/sandbox/runtime/trunk/src/main/native/include/acr/atomic.h (with
props)
commons/sandbox/runtime/trunk/src/main/native/os/bsdx/atomic.c (with
props)
commons/sandbox/runtime/trunk/src/main/native/os/linux/atomic.c (with
props)
commons/sandbox/runtime/trunk/src/main/native/os/solaris/atomic.c (with
props)
commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_sync.h (with
props)
commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_sync.h (with
props)
commons/sandbox/runtime/trunk/src/main/native/os/win32/atomic.c (with
props)
Modified:
commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
commons/sandbox/runtime/trunk/src/main/native/os/linux/epoll.c
commons/sandbox/runtime/trunk/src/main/native/os/unix/pollset.c
Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=1139498&r1=1139497&r2=1139498&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Sat Jun 25
07:24:33 2011
@@ -75,6 +75,7 @@ ZLIB_SOURCES=\
ASMSOURCES=
WIN32_SOURCES=\
+ $(TOPDIR)\os\win32\atomic.c \
$(TOPDIR)\os\win32\dirent.c \
$(TOPDIR)\os\win32\dso.c \
$(TOPDIR)\os\win32\exec.c \
Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in?rev=1139498&r1=1139497&r2=1139498&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in Sat Jun 25
07:24:33 2011
@@ -78,16 +78,20 @@ UNIX_SOURCES=\
$(TOPDIR)/os/unix/util.c
BSDX_SOURCES=\
+ $(TOPDIR)/os/bsdx/atomic.c \
$(TOPDIR)/os/bsdx/os.c
DARWIN_SOURCES=\
+ $(TOPDIR)/os/bsdx/atomic.c \
$(TOPDIR)/os/darwin/os.c
HPUX_SOURCES=\
$(TOPDIR)/os/hpux/os.c
LINUX_SOURCES=\
+ $(TOPDIR)/os/linux/atomic.c \
$(TOPDIR)/os/linux/epoll.c \
$(TOPDIR)/os/linux/misc.c \
$(TOPDIR)/os/linux/os.c
SOLARIS_SOURCES=\
+ $(TOPDIR)/os/solaris/atomic.c \
$(TOPDIR)/os/solaris/os.c
LIBSOURCES=\
Added: commons/sandbox/runtime/trunk/src/main/native/include/acr/atomic.h
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/atomic.h?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/atomic.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/atomic.h Sat Jun
25 07:24:33 2011
@@ -0,0 +1,45 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _ACR_ATOMIC_H_
+#define _ACR_ATOMIC_H_
+
+#include "acr/stdtypes.h"
+
+/**
+ * Atomic operation routines...
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void AcrCpuFence(void);
+void AcrMemoryFence(void);
+
+int AcrAtomic32Inc(volatile acr_atomic32_t *val);
+int AcrAtomic32Dec(volatile acr_atomic32_t *val);
+
+int AcrAtomic32Cas(volatile acr_atomic32_t *val, int cmp, int set);
+void *AcrAtomic32CasPtr(void * volatile *val, const void *cmp, void *set);
+int AcrAtomic32Set(volatile acr_atomic32_t *val, int num);
+void *AcrAtomic32SetPtr(void * volatile *val, void *set);
+int AcrAtomic32Equ(volatile acr_atomic32_t *val, int num);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ACR_ATOMIC_H_ */
Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr/atomic.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/native/os/bsdx/atomic.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/bsdx/atomic.c?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/bsdx/atomic.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/bsdx/atomic.c Sat Jun 25
07:24:33 2011
@@ -0,0 +1,117 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr/atomic.h"
+#include "arch_sync.h"
+
+
+#if USE_ATOMICS_WRAPPER
+UNUSED_SOURCE_FILE(atomic);
+#else
+void AcrCpuFence()
+{
+ _PR_COMPILER_FENCE();
+}
+
+void AcrMemoryFence()
+{
+ _PR_RWMEMORY_FENCE();
+}
+
+int AcrAtomic32Inc(volatile acr_atomic32_t *val)
+{
+#if USE_BUILTIN_ATOMICS
+ return (int)__sync_add_and_fetch(val, 1);
+#else
+ _PR_COMPILER_FENCE();
+ return (int)(++(*val));
+#endif
+}
+
+int AcrAtomic32Dec(volatile acr_atomic32_t *val)
+{
+#if USE_BUILTIN_ATOMICS
+ return (int)__sync_sub_and_fetch(val, 1);
+#else
+ _PR_COMPILER_FENCE();
+ return (int)(--(*val));
+#endif
+}
+
+int AcrAtomic32Cas(volatile acr_atomic32_t *val, int cmp, int set)
+{
+#if USE_BUILTIN_ATOMICS
+ return (int)__sync_val_compare_and_swap(val, cmp, set);
+#else
+ _PR_COMPILER_FENCE();
+ acr_atomic32_t org = *val;
+ if (org == (acr_atomic32_t)cmp)
+ *val = (acr_atomic32_t)set;
+ return (int)org;
+#endif
+}
+
+void *AcrAtomic32CasPtr(void * volatile *val, const void *cmp, void *set)
+{
+#if USE_BUILTIN_ATOMICS
+ return (void *)__sync_val_compare_and_swap(val, cmp, set);
+#else
+ _PR_COMPILER_FENCE();
+ void *org = *((void **)val);
+ if (org == cmp) {
+ *val = set;
+ }
+ return org;
+#endif
+}
+
+int AcrAtomic32Set(volatile acr_atomic32_t *val, int num)
+{
+#if USE_BUILTIN_ATOMICS
+ __sync_synchronize();
+ return (int)__sync_lock_test_and_set(val, num);
+#else
+ _PR_COMPILER_FENCE();
+ acr_atomic32_t org = *val;
+ *val = num;
+ return (int)org;
+#endif
+}
+
+void *AcrAtomic32SetPtr(void * volatile *val, void *set)
+{
+#if USE_BUILTIN_ATOMICS
+ __sync_synchronize();
+ return (void *)__sync_lock_test_and_set(val, set);
+#else
+ _PR_COMPILER_FENCE();
+ void *org = *((void **)val);
+ *val = set;
+ return org;
+#endif
+}
+
+int AcrAtomic32Equ(volatile acr_atomic32_t *val, int num)
+{
+#if USE_BUILTIN_ATOMICS
+ return __sync_bool_compare_and_swap(val, num, num);
+#else
+ _PR_COMPILER_FENCE();
+ return *val == (acr_atomic32_t)num;
+#endif
+}
+
+#endif /* USE_ATOMICS_WRAPPER */
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/bsdx/atomic.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/native/os/linux/atomic.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/linux/atomic.c?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/linux/atomic.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/linux/atomic.c Sat Jun 25
07:24:33 2011
@@ -0,0 +1,117 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr/atomic.h"
+#include "arch_sync.h"
+
+
+#if USE_ATOMICS_WRAPPER
+UNUSED_SOURCE_FILE(atomic);
+#else
+void AcrCpuFence()
+{
+ _PR_COMPILER_FENCE();
+}
+
+void AcrMemoryFence()
+{
+ _PR_RWMEMORY_FENCE();
+}
+
+int AcrAtomic32Inc(volatile acr_atomic32_t *val)
+{
+#if USE_BUILTIN_ATOMICS
+ return (int)__sync_add_and_fetch(val, 1);
+#else
+ _PR_COMPILER_FENCE();
+ return (int)(++(*val));
+#endif
+}
+
+int AcrAtomic32Dec(volatile acr_atomic32_t *val)
+{
+#if USE_BUILTIN_ATOMICS
+ return (int)__sync_sub_and_fetch(val, 1);
+#else
+ _PR_COMPILER_FENCE();
+ return (int)(--(*val));
+#endif
+}
+
+int AcrAtomic32Cas(volatile acr_atomic32_t *val, int cmp, int set)
+{
+#if USE_BUILTIN_ATOMICS
+ return (int)__sync_val_compare_and_swap(val, cmp, set);
+#else
+ _PR_COMPILER_FENCE();
+ acr_atomic32_t org = *val;
+ if (org == (acr_atomic32_t)cmp)
+ *val = (acr_atomic32_t)set;
+ return (int)org;
+#endif
+}
+
+void *AcrAtomic32CasPtr(void * volatile *val, const void *cmp, void *set)
+{
+#if USE_BUILTIN_ATOMICS
+ return (void *)__sync_val_compare_and_swap(val, cmp, set);
+#else
+ _PR_COMPILER_FENCE();
+ void *org = *((void **)val);
+ if (org == cmp) {
+ *val = set;
+ }
+ return org;
+#endif
+}
+
+int AcrAtomic32Set(volatile acr_atomic32_t *val, int num)
+{
+#if USE_BUILTIN_ATOMICS
+ __sync_synchronize();
+ return (int)__sync_lock_test_and_set(val, num);
+#else
+ _PR_COMPILER_FENCE();
+ acr_atomic32_t org = *val;
+ *val = num;
+ return (int)org;
+#endif
+}
+
+void *AcrAtomic32SetPtr(void * volatile *val, void *set)
+{
+#if USE_BUILTIN_ATOMICS
+ __sync_synchronize();
+ return (void *)__sync_lock_test_and_set(val, set);
+#else
+ _PR_COMPILER_FENCE();
+ void *org = *((void **)val);
+ *val = set;
+ return org;
+#endif
+}
+
+int AcrAtomic32Equ(volatile acr_atomic32_t *val, int num)
+{
+#if USE_BUILTIN_ATOMICS
+ return __sync_bool_compare_and_swap(val, num, num);
+#else
+ _PR_COMPILER_FENCE();
+ return *val == (acr_atomic32_t)num;
+#endif
+}
+
+#endif /* USE_ATOMICS_WRAPPER */
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/linux/atomic.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/native/os/linux/epoll.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/linux/epoll.c?rev=1139498&r1=1139497&r2=1139498&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/linux/epoll.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/linux/epoll.c Sat Jun 25
07:24:33 2011
@@ -15,6 +15,7 @@
*/
#include "acr/clazz.h"
+#include "acr/atomic.h"
#include "acr/memory.h"
#include "acr/jniapi.h"
#include "acr/port.h"
@@ -54,14 +55,14 @@ typedef struct acr_pollset_t {
* might still be inside a _epoll()
*/
ACR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
- struct epoll_event *epset;
- int epfd;
- int used;
- int size;
- volatile int state;
- int wpipe[2];
- pthread_mutex_t mutex;
- pthread_cond_t wakeup;
+ struct epoll_event *epset;
+ int epfd;
+ int used;
+ int size;
+ volatile acr_atomic32_t state;
+ int wpipe[2];
+ pthread_mutex_t mutex;
+ pthread_cond_t wakeup;
} acr_pollset_t;
static short ieventt(int event)
@@ -199,15 +200,15 @@ ACR_NET_EXPORT(jint, UnixSelector, clr0)
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- while (ps->state != 0) {
- if (ps->state == PSS_DESTROY) {
+ while (!AcrAtomic32Equ(&ps->state, 0)) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
/* Interrupted by destroy0 */
pthread_mutex_unlock(&ps->mutex);
return 0;
}
- if (ps->state == PSS_POLL) {
+ if (AcrAtomic32Equ(&ps->state, PSS_POLL)) {
char ch = 1;
- ps->state = PSS_WAKEUP;
+ AcrAtomic32Set(&ps->state, PSS_WAKEUP);
r_write(ps->wpipe[1], &ch, 1);
}
/* Wait until the wait0 call breaks.
@@ -241,9 +242,9 @@ ACR_NET_EXPORT(void, UnixSelector, wakeu
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state == PSS_POLL) {
+ if (AcrAtomic32Equ(&ps->state, PSS_POLL)) {
char ch = 1;
- ps->state = PSS_WAKEUP;
+ AcrAtomic32Set(&ps->state, PSS_WAKEUP);
r_write(ps->wpipe[1], &ch, 1);
}
pthread_mutex_unlock(&ps->mutex);
@@ -270,7 +271,7 @@ ACR_NET_EXPORT(jint, UnixSelector, add0)
acr_fd_t *fd = J2P(fp, acr_fd_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state == PSS_DESTROY) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
/* Already destroyed */
goto cleanup;
}
@@ -347,7 +348,7 @@ ACR_NET_EXPORT(jint, UnixSelector, del0)
acr_fd_t *fd = J2P(fp, acr_fd_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state == PSS_DESTROY || ps->used < 2) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY) || ps->used < 2) {
/* Already destroyed */
goto cleanup;
}
@@ -377,9 +378,8 @@ ACR_NET_EXPORT(int, UnixSelector, destro
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state != 0) {
- int state = ps->state;
- ps->state = PSS_DESTROY;
+ if (!AcrAtomic32Equ(&ps->state, 0)) {
+ int state = AcrAtomic32Set(&ps->state, PSS_DESTROY);
if (state == PSS_POLL) {
char ch = 1;
r_write(ps->wpipe[1], &ch, 1);
@@ -393,7 +393,7 @@ ACR_NET_EXPORT(int, UnixSelector, destro
return rc;
}
}
- ps->state = PSS_DESTROY;
+ AcrAtomic32Set(&ps->state, PSS_DESTROY);
ps->used = 0;
pthread_mutex_unlock(&ps->mutex);
r_close(ps->wpipe[0]);
@@ -437,7 +437,7 @@ ACR_NET_EXPORT(jint, UnixSelector, wait0
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state != 0) {
+ if (!AcrAtomic32Equ(&ps->state, 0)) {
/* Note that this should never happen if api is correctly used.
* wait cannot be run from multiple threads and cannot be run
* after destroy.
@@ -454,7 +454,7 @@ ACR_NET_EXPORT(jint, UnixSelector, wait0
return 0;
}
- ps->state = PSS_POLL;
+ AcrAtomic32Set(&ps->state, PSS_POLL);
pthread_mutex_unlock(&ps->mutex);
if (timeout > 0)
tmx = AcrTimeMilliseconds() + timeout;
@@ -476,7 +476,7 @@ ACR_NET_EXPORT(jint, UnixSelector, wait0
if (ns == -1)
rc = ACR_GET_OS_ERROR();
pthread_mutex_lock(&ps->mutex);
- if (ps->state == PSS_DESTROY) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
/* Interrupted by destroy0 */
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
@@ -484,7 +484,7 @@ ACR_NET_EXPORT(jint, UnixSelector, wait0
}
if (rc != 0) {
/* Error during poll */
- ps->state = 0;
+ AcrAtomic32Set(&ps->state, 0);
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
ACR_THROW_NET_ERROR(rc);
@@ -492,21 +492,21 @@ ACR_NET_EXPORT(jint, UnixSelector, wait0
}
if (ns == 0) {
/* Timeout occured */
- ps->state = PSS_WAIT;
+ AcrAtomic32Set(&ps->state, PSS_WAIT);
pevents = JARRAY_CRITICAL(jshort, revents);
goto cleanup;
}
- if (ps->state == PSS_WAKEUP) {
+ if (AcrAtomic32Equ(&ps->state, PSS_WAKEUP)) {
/* Interrupted by wakeup0.
* Drain the wakeup pipe.
*/
AcrDrainPipe(ps->wpipe[0]);
- ps->state = 0;
+ AcrAtomic32Set(&ps->state, 0);
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
return 0;
}
- ps->state = PSS_WAIT;
+ AcrAtomic32Set(&ps->state, PSS_WAIT);
pevents = JARRAY_CRITICAL(jshort, revents);
/* Cycle trough the descriptors */
for (i = 0; i < ns; i++) {
@@ -565,7 +565,7 @@ cleanup:
RELEASE_CRITICAL(revents, pevents);
/* Shift all PFDs in the Dead Ring to the Free Ring */
ACR_RING_CONCAT(&ps->free_ring, &ps->dead_ring, pfd_elem_t, link);
- ps->state = 0;
+ AcrAtomic32Set(&ps->state, 0);
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
return rv;
Added: commons/sandbox/runtime/trunk/src/main/native/os/solaris/atomic.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/solaris/atomic.c?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/solaris/atomic.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/solaris/atomic.c Sat Jun
25 07:24:33 2011
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr/atomic.h"
+#include "arch_sync.h"
+
+void AcrCpuFence()
+{
+ _PR_COMPILER_FENCE();
+}
+
+void AcrmemoryFence()
+{
+ _PR_RWMEMORY_FENCE();
+}
+
+int AcrAtomic32Inc(volatile acr_atomic32_t *val)
+{
+ return (int)atomic_inc_32_nv(val);
+}
+
+int AcrAtomic32Dec(volatile acr_atomic32_t *val)
+{
+ return (int)atomic_dec_32_nv(val);
+}
+
+int AcrAtomic32Cas(volatile acr_atomic32_t *val, int cmp, int set)
+{
+ return (int)atomic_cas_32(val, (uint32_t)cmp, (uint32_t)set);
+}
+
+void *AcrAtomic32CasPtr(void * volatile *val, const void *cmp, void *set)
+{
+ return atomic_cas_ptr(val, (void *)cmp, set);
+}
+
+int AcrAtomic32Set(volatile acr_atomic32_t *val, int num)
+{
+ return (int)atomic_swap_32(val, (uint32_t)num);
+}
+
+void *AcrAtomic32SetPtr(void * volatile *val, void *set)
+{
+ return atomic_swap_ptr(val, set);
+}
+
+int AcrAtomic32Equ(volatile acr_atomic32_t *val, int num)
+{
+ uint32_t cmp = num;
+ return atomic_cas_32(val, cmp, cmp) == cmp;
+}
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/solaris/atomic.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_sync.h
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_sync.h?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_sync.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_sync.h Sat Jun
25 07:24:33 2011
@@ -0,0 +1,61 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ACR_ARCH_SYNC_H_
+#define _ACR_ARCH_SYNC_H_
+
+#include "acr/stddefs.h"
+
+#if defined(_SOLARIS)
+#include <atomic.h>
+#endif
+
+#if defined(__GNUC__)
+# if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
+# define USE_ATOMICS_WRAPPER 0
+# define USE_BUILTIN_ATOMICS 1
+# else
+# define USE_ATOMICS_WRAPPER 1
+# define USE_BUILTIN_ATOMICS 0
+# endif
+# define _PR_COMPILER_FENCE() __asm__ __volatile__("" : : : "memory")
+# if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
+# define _PR_RWMEMORY_FENCE() __sync_synchronize()
+# else
+# if defined(_I386_) || defined(_X86_64_)
+# define __mfence "mfence"
+# elif defined(_PPC_) || defined(_PPC_64_)
+# define __mfence "sync"
+# else
+# define __mfence ""
+# endif
+# define _PR_RWMEMORY_FENCE() __asm__ __volatile__(__mfence : : : "memory")
+# endif
+#else
+# if defined(_SOLARIS)
+# define USE_BUILTIN_ATOMICS 1
+# define USE_ATOMICS_WRAPPER 0
+# define _PR_COMPILER_FENCE() membar_consumer()
+# define _PR_RWMEMORY_FENCE() do { membar_producer(); membar_consumer(); }
while (0)
+# else
+# define USE_BUILTIN_ATOMICS 0
+# define USE_ATOMICS_WRAPPER 1
+# define _PR_COMPILER_FENCE() (void)0
+# define _PR_RWMEMORY_FENCE() (void)0
+# endif
+#endif
+
+#endif /* _ACR_ARCH_SYNC_H_ */
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/unix/arch_sync.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/pollset.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/pollset.c?rev=1139498&r1=1139497&r2=1139498&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/pollset.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/pollset.c Sat Jun 25
07:24:33 2011
@@ -15,6 +15,7 @@
*/
#include "acr/clazz.h"
+#include "acr/atomic.h"
#include "acr/memory.h"
#include "acr/jniapi.h"
#include "acr/port.h"
@@ -30,6 +31,13 @@
#define PSS_WAIT 3
#define PSS_WAKEUP 4
+#define WAKEUP_IF_POLL() \
+ if (AcrAtomic32Equ(&ps->state, PSS_POLL)) { \
+ char ch = 1; \
+ AcrAtomic32Set(&ps->state, PSS_WAKEUP); \
+ r_write(ps->wpipe[1], &ch, 1); \
+ } else (void)0
+
typedef struct acr_pollfd_t {
jobject obj;
acr_time_t ttl;
@@ -37,14 +45,14 @@ typedef struct acr_pollfd_t {
} acr_pollfd_t;
typedef struct acr_pollset_t {
- struct pollfd *fdset;
- acr_pollfd_t *ooset;
- int used;
- int size;
- volatile int state;
- int wpipe[2];
- pthread_mutex_t mutex;
- pthread_cond_t wakeup;
+ struct pollfd *fdset;
+ acr_pollfd_t *ooset;
+ int used;
+ int size;
+ volatile acr_atomic32_t state;
+ int wpipe[2];
+ pthread_mutex_t mutex;
+ pthread_cond_t wakeup;
} acr_pollset_t;
static short ieventt(int event)
@@ -144,9 +152,8 @@ ACR_NET_EXPORT(int, PollSelector, destro
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state != 0) {
- int state = ps->state;
- ps->state = PSS_DESTROY;
+ if (!AcrAtomic32Equ(&ps->state, 0)) {
+ int state = AcrAtomic32Set(&ps->state, PSS_DESTROY);
if (state == PSS_POLL) {
char ch = 1;
r_write(ps->wpipe[1], &ch, 1);
@@ -160,7 +167,7 @@ ACR_NET_EXPORT(int, PollSelector, destro
return rc;
}
}
- ps->state = PSS_DESTROY;
+ AcrAtomic32Set(&ps->state, PSS_DESTROY);
for (i = 1; i < ps->used; i++) {
AcrSelectionKeyReset(env, ps->ooset[i].obj);
/* Invalidate the container. */
@@ -186,17 +193,13 @@ ACR_NET_EXPORT(jint, PollSelector, clr0)
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- while (ps->state != 0) {
- if (ps->state == PSS_DESTROY) {
+ while (!AcrAtomic32Equ(&ps->state, 0)) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
/* Interrupted by destroy0 */
pthread_mutex_unlock(&ps->mutex);
return 0;
}
- if (ps->state == PSS_POLL) {
- char ch = 1;
- ps->state = PSS_WAKEUP;
- r_write(ps->wpipe[1], &ch, 1);
- }
+ WAKEUP_IF_POLL();
/* Wait until the wait0 call breaks.
* Since we set the state to DESTROY
* wait0 will return 0.
@@ -222,11 +225,7 @@ ACR_NET_EXPORT(void, PollSelector, wakeu
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state == PSS_POLL) {
- char ch = 1;
- ps->state = PSS_WAKEUP;
- r_write(ps->wpipe[1], &ch, 1);
- }
+ WAKEUP_IF_POLL();
pthread_mutex_unlock(&ps->mutex);
}
@@ -253,7 +252,7 @@ ACR_NET_EXPORT(jint, PollSelector, wait0
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- if (ps->state != 0) {
+ if (!AcrAtomic32Equ(&ps->state, 0)) {
/* Note that this should never happen if api is correctly used.
* wait cannot be run from multiple threads and cannot be run
* after destroy.
@@ -270,7 +269,7 @@ ACR_NET_EXPORT(jint, PollSelector, wait0
return 0;
}
- ps->state = PSS_POLL;
+ AcrAtomic32Set(&ps->state, PSS_POLL);
pthread_mutex_unlock(&ps->mutex);
if (timeout > 0)
tmx = AcrTimeMilliseconds() + timeout;
@@ -292,7 +291,7 @@ ACR_NET_EXPORT(jint, PollSelector, wait0
if (ns == -1)
rc = ACR_GET_OS_ERROR();
pthread_mutex_lock(&ps->mutex);
- if (ps->state == PSS_DESTROY) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
/* Interrupted by destroy0 */
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
@@ -300,7 +299,7 @@ ACR_NET_EXPORT(jint, PollSelector, wait0
}
if (rc != 0) {
/* Error during poll */
- ps->state = 0;
+ AcrAtomic32Set(&ps->state, 0);
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
ACR_THROW_NET_ERROR(rc);
@@ -328,7 +327,7 @@ ACR_NET_EXPORT(jint, PollSelector, wait0
* Wakeup pipe is always at index zero.
*/
AcrDrainPipe(ps->wpipe[0]);
- ps->state = 0;
+ AcrAtomic32Set(&ps->state, 0);
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
return 0;
@@ -400,7 +399,7 @@ cleanup:
}
}
}
- ps->state = 0;
+ AcrAtomic32Set(&ps->state, 0);
pthread_cond_broadcast(&ps->wakeup);
pthread_mutex_unlock(&ps->mutex);
return rv;
@@ -414,16 +413,12 @@ ACR_NET_EXPORT(jint, PollSelector, add0)
acr_fd_t *fd = J2P(fp, acr_fd_t *);
pthread_mutex_lock(&ps->mutex);
- while (ps->state != 0) {
- if (ps->state == PSS_DESTROY) {
+ while (!AcrAtomic32Equ(&ps->state, 0)) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
rc = 0;
goto cleanup;
}
- if (ps->state == PSS_POLL) {
- char ch = 1;
- ps->state = PSS_WAKEUP;
- r_write(ps->wpipe[1], &ch, 1);
- }
+ WAKEUP_IF_POLL();
if ((rc = pthread_cond_wait(&ps->wakeup, &ps->mutex)) != 0)
goto cleanup;
}
@@ -473,16 +468,14 @@ ACR_NET_EXPORT(jint, PollSelector, del0)
acr_pollset_t *ps = J2P(pollset, acr_pollset_t *);
pthread_mutex_lock(&ps->mutex);
- while (ps->state != 0) {
- if (ps->state == PSS_DESTROY) {
+ if (ps->used < 2)
+ goto cleanup;
+ while (!AcrAtomic32Equ(&ps->state, 0)) {
+ if (AcrAtomic32Equ(&ps->state, PSS_DESTROY)) {
rc = 0;
goto cleanup;
}
- if (ps->state == PSS_POLL) {
- char ch = 1;
- ps->state = PSS_WAKEUP;
- r_write(ps->wpipe[1], &ch, 1);
- }
+ WAKEUP_IF_POLL();
if ((rc = pthread_cond_wait(&ps->wakeup, &ps->mutex)) != 0)
goto cleanup;
}
Added: commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_sync.h
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_sync.h?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_sync.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_sync.h Sat Jun
25 07:24:33 2011
@@ -0,0 +1,34 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ACR_ARCH_SYNC_H_
+#define _ACR_ARCH_SYNC_H_
+
+#include "acr/stddefs.h"
+
+#if HAVE_INTRIN_H
+# include <intrin.h>
+# pragma intrinsic(_ReadWriteBarrier)
+# define _PR_COMPILER_FENCE() _ReadWriteBarrier()
+#else
+# define _PR_COMPILER_FENCE() (void)0
+#endif
+#define _PR_RWMEMORY_FENCE() MemoryBarrier()
+
+#define USE_ATOMICS_WRAPPER 0
+#define USE_BUILTIN_ATOMICS 1
+
+#endif /* _ACR_ARCH_SYNC_H_ */
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_sync.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/native/os/win32/atomic.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/atomic.c?rev=1139498&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/atomic.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/atomic.c Sat Jun 25
07:24:33 2011
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr/atomic.h"
+#include "arch_sync.h"
+
+void AcrCpuFence()
+{
+ _PR_COMPILER_FENCE();
+}
+
+void AcrMemoryFence()
+{
+ _PR_RWMEMORY_FENCE();
+}
+
+int AcrAtomic32Inc(volatile acr_atomic32_t *val)
+{
+ return (int)InterlockedIncrement(val);
+}
+
+int AcrAtomic32Dec(volatile acr_atomic32_t *val)
+{
+ return (int)InterlockedDecrement(val);
+}
+
+int AcrAtomic32Cas(volatile acr_atomic32_t *val, int cmp, int set)
+{
+ return (int)InterlockedCompareExchange(val, (long)cmp, (long)set);
+}
+
+void *AcrAtomic32CasPtr(void * volatile *val, const void *cmp, void *set)
+{
+ return InterlockedCompareExchangePointer(val, (void *)cmp, set);
+}
+
+int AcrAtomic32Set(volatile acr_atomic32_t *val, int num)
+{
+ return (int)InterlockedExchange(val, (long)num);
+}
+
+void *AcrAtomic32SetPtr(void * volatile *val, void *set)
+{
+ return InterlockedExchangePointer(val, set);
+}
+
+int AcrAtomic32Equ(volatile acr_atomic32_t *val, int num)
+{
+ long cmp = (long)num;
+ return InterlockedCompareExchange(val, cmp, cmp) == cmp;
+}
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/atomic.c
------------------------------------------------------------------------------
svn:eol-style = native