forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ovs-atomic: Use raw types, not structs, when locks are required.
Until now, the GCC 4+ and pthreads implementations of atomics have used struct wrappers for their atomic types. This had the advantage of allowing a mutex to be wrapped in, in some cases, and of better type-checking by preventing stray uses of atomic variables other than through one of the atomic_*() functions or macros. However, the mutex meant that an atomic_destroy() function-like macro needed to be used. The struct wrapper also made it impossible to define new atomic types that were compatible with each other without using a typedef. For example, one could not simply define a macro like #define ATOMIC(TYPE) struct { TYPE value; } and then have two declarations like: ATOMIC(void *) x; ATOMIC(void *) y; and do anything with these objects that require type-compatibility, even "&x == &y", because the two structs are not compatible. One can do it through a typedef: typedef ATOMIC(void *) atomic_voidp; atomic_voidp x, y; but that is inconvenient, especially because of the need to invent a name for the type. This commit aims to ease the problem by getting rid of the wrapper structs in the cases where the atomic library used them. It gets rid of the mutexes, in the cases where they are still needed, by using a global array of mutexes instead. This commit also defines the ATOMIC macro described above and documents its use in ovs-atomic.h. Signed-off-by: Ben Pfaff <[email protected]> Acked-by: Andy Zhou <[email protected]>
- Loading branch information
Showing
7 changed files
with
175 additions
and
258 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2013, 2014 Nicira, Inc. | ||
* | ||
* Licensed 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 <config.h> | ||
|
||
#include "ovs-atomic.h" | ||
#include "hash.h" | ||
#include "ovs-thread.h" | ||
|
||
#ifdef OVS_ATOMIC_LOCKED_IMPL | ||
static struct ovs_mutex * | ||
mutex_for_pointer(void *p) | ||
{ | ||
OVS_ALIGNED_STRUCT(CACHE_LINE_SIZE, aligned_mutex) { | ||
struct ovs_mutex mutex; | ||
char pad[PAD_SIZE(sizeof(struct ovs_mutex), CACHE_LINE_SIZE)]; | ||
}; | ||
|
||
static struct aligned_mutex atomic_mutexes[] = { | ||
#define MUTEX_INIT { .mutex = OVS_MUTEX_INITIALIZER } | ||
#define MUTEX_INIT4 MUTEX_INIT, MUTEX_INIT, MUTEX_INIT, MUTEX_INIT | ||
#define MUTEX_INIT16 MUTEX_INIT4, MUTEX_INIT4, MUTEX_INIT4, MUTEX_INIT4 | ||
MUTEX_INIT16, MUTEX_INIT16, | ||
}; | ||
BUILD_ASSERT_DECL(IS_POW2(ARRAY_SIZE(atomic_mutexes))); | ||
|
||
uint32_t hash = hash_pointer(p, 0); | ||
uint32_t indx = hash & (ARRAY_SIZE(atomic_mutexes) - 1); | ||
return &atomic_mutexes[indx].mutex; | ||
} | ||
|
||
void | ||
atomic_lock__(void *p) | ||
OVS_ACQUIRES(mutex_for_pointer(p)) | ||
{ | ||
ovs_mutex_lock(mutex_for_pointer(p)); | ||
} | ||
|
||
void | ||
atomic_unlock__(void *p) | ||
OVS_RELEASES(mutex_for_pointer(p)) | ||
{ | ||
ovs_mutex_unlock(mutex_for_pointer(p)); | ||
} | ||
#endif /* OVS_ATOMIC_LOCKED_IMPL */ |
Oops, something went wrong.