Skip to content

Commit 1b68598

Browse files
committed
Fix atomics 64bits (#9)
* micro-ROS changes over dashing Feature/add security directory (#1) * Added security directory * Updated security directory Feature/avoid filesystem and allocation (#2) * Included RCUTILS_NO_FILESYSTEM and RCUTILS_AVOID_DYNAMIC_ALLOCATION * Added no filesystem options * Default allocators write access * Avoid dynamic allocation and no filesytem on error handling * Typo * New flags for filesystem and avoid dynamic * Error handling template * New allocator approach Add test_security_directory test from rcl. (#3) Merge pull request #4 from micro-ROS/feature/zephyr_fixes Feature/zephyr fixes CMake refactor (#5) Update approach (#6) * Update approach * Remove target_compile_definitions and refactor flags install * Added RCUTILS_NO_FILESYSTEM on new functions * Added RCUTILS_NO_FILESYSTEM on new functions Co-authored-by: Pablo Garrido <[email protected]> * Initial changes * Add hashing and lock pool * Updates Co-authored-by: Jose Antonio Moral <[email protected]> Fix atomics 64bits (#9)
1 parent 737e176 commit 1b68598

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ project(rcutils)
55
option(RCUTILS_NO_THREAD_SUPPORT "Disable thread support." OFF)
66
option(RCUTILS_NO_FILESYSTEM "Disable filesystem usage." OFF)
77
option(RCUTILS_AVOID_DYNAMIC_ALLOCATION "Disable dynamic allocations." OFF)
8+
option(RCUTILS_NO_64_ATOMIC "Disable support for 64 bits atomic operations." OFF)
89

910
# Default to C11
1011
if(NOT CMAKE_C_STANDARD)
@@ -74,6 +75,7 @@ set(rcutils_sources
7475
src/time.c
7576
${time_impl_c}
7677
src/uint8_array.c
78+
$<$<BOOL:${RCUTILS_NO_64_ATOMIC}>:src/atomic_64bits.c>
7779
)
7880

7981
set_source_files_properties(

src/atomic_64bits.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifdef __cplusplus
16+
extern "C"
17+
{
18+
#endif
19+
20+
#include <stdint.h>
21+
#include <stdbool.h>
22+
23+
#define FLAGS_LEN 23
24+
25+
static bool * get_memory_lock(void *address)
26+
{
27+
static bool memory_locks[FLAGS_LEN] = { 0 };
28+
uintptr_t a = (uintptr_t)(address);
29+
30+
// Public domain hash function taken from http://burtleburtle.net/bob/hash/integer.html
31+
a = (a ^ 61) ^ (a >> 16);
32+
a = a + (a << 3);
33+
a = a ^ (a >> 4);
34+
a = a * 0x27d4eb2d;
35+
a = a ^ (a >> 15);
36+
37+
a = a % FLAGS_LEN;
38+
return memory_locks + a;
39+
}
40+
41+
void lock_memory(uint64_t *address){
42+
bool * memory_lock = get_memory_lock(address);
43+
44+
while (__atomic_test_and_set(memory_lock, __ATOMIC_ACQUIRE) == 1);
45+
}
46+
47+
void unlock_memory(uint64_t *address){
48+
bool * memory_lock = get_memory_lock(address);
49+
50+
__atomic_clear(memory_lock, __ATOMIC_RELEASE);
51+
}
52+
53+
uint64_t __atomic_load_8(uint64_t *mem, int model) {
54+
(void) model;
55+
56+
lock_memory(mem);
57+
uint64_t ret = *mem;
58+
unlock_memory(mem);
59+
return ret;
60+
}
61+
62+
void __atomic_store_8(uint64_t *mem, uint64_t val, int model) {
63+
(void) model;
64+
65+
lock_memory(mem);
66+
*mem = val;
67+
unlock_memory(mem);
68+
}
69+
70+
uint64_t __atomic_exchange_8(uint64_t *mem, uint64_t val, int model) {
71+
(void) model;
72+
73+
lock_memory(mem);
74+
uint64_t ret = *mem;
75+
*mem = val;
76+
unlock_memory(mem);
77+
return ret;
78+
}
79+
80+
uint64_t __atomic_fetch_add_8(uint64_t *mem, uint64_t val, int model) {
81+
(void) model;
82+
83+
lock_memory(mem);
84+
uint64_t ret = *mem;
85+
*mem += val;
86+
unlock_memory(mem);
87+
return ret;
88+
}
89+
90+
#ifdef __cplusplus
91+
}
92+
#endif

0 commit comments

Comments
 (0)