qom/object: update class cache atomically
The idiom CPU_GET_CLASS(cpu) is fairly extensively used in various threads and trips of ThreadSanitizer due to the fact it updates obj->class->object_cast_cache behind the scenes. As this is just a fast-path cache there is no need to lock updates. However to ensure defined C11 behaviour across threads we need to use the plain atomic_read/set primitives and keep the sanitizer happy. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20160930213106.20186-7-alex.bennee@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
f96a8cc3c6
commit
b6b3ccfda0
15
qom/object.c
15
qom/object.c
@ -614,7 +614,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
|
||||
Object *inst;
|
||||
|
||||
for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
if (obj->class->object_cast_cache[i] == typename) {
|
||||
if (atomic_read(&obj->class->object_cast_cache[i]) == typename) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -631,10 +631,10 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
|
||||
|
||||
if (obj && obj == inst) {
|
||||
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
obj->class->object_cast_cache[i - 1] =
|
||||
obj->class->object_cast_cache[i];
|
||||
atomic_set(&obj->class->object_cast_cache[i - 1],
|
||||
atomic_read(&obj->class->object_cast_cache[i]));
|
||||
}
|
||||
obj->class->object_cast_cache[i - 1] = typename;
|
||||
atomic_set(&obj->class->object_cast_cache[i - 1], typename);
|
||||
}
|
||||
|
||||
out:
|
||||
@ -704,7 +704,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
|
||||
int i;
|
||||
|
||||
for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
if (class->class_cast_cache[i] == typename) {
|
||||
if (atomic_read(&class->class_cast_cache[i]) == typename) {
|
||||
ret = class;
|
||||
goto out;
|
||||
}
|
||||
@ -725,9 +725,10 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
|
||||
#ifdef CONFIG_QOM_CAST_DEBUG
|
||||
if (class && ret == class) {
|
||||
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||
class->class_cast_cache[i - 1] = class->class_cast_cache[i];
|
||||
atomic_set(&class->class_cast_cache[i - 1],
|
||||
atomic_read(&class->class_cast_cache[i]));
|
||||
}
|
||||
class->class_cast_cache[i - 1] = typename;
|
||||
atomic_set(&class->class_cast_cache[i - 1], typename);
|
||||
}
|
||||
out:
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user