Skip to content

Commit

Permalink
qom/object: update class cache atomically
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Marc-André Lureau <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
stsquad authored and bonzini committed Oct 4, 2016
1 parent f96a8cc commit b6b3ccf
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions qom/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -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:
Expand Down Expand Up @@ -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;
}
Expand All @@ -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
Expand Down

0 comments on commit b6b3ccf

Please sign in to comment.