mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 16:35:30 +00:00
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. Backports commit b6b3ccfda015dcd5ab50f70c189ee5cc6c622e91 from qemu
This commit is contained in:
parent
bf72733576
commit
12d7e946a1
|
@ -498,7 +498,7 @@ Object *object_dynamic_cast_assert(struct uc_struct *uc, Object *obj, const char
|
||||||
Object *inst;
|
Object *inst;
|
||||||
|
|
||||||
for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -515,10 +515,10 @@ Object *object_dynamic_cast_assert(struct uc_struct *uc, Object *obj, const char
|
||||||
|
|
||||||
if (obj && obj == inst) {
|
if (obj && obj == inst) {
|
||||||
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
||||||
obj->class->object_cast_cache[i - 1] =
|
atomic_set(&obj->class->object_cast_cache[i - 1],
|
||||||
obj->class->object_cast_cache[i];
|
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:
|
out:
|
||||||
|
@ -585,7 +585,7 @@ ObjectClass *object_class_dynamic_cast_assert(struct uc_struct *uc, ObjectClass
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; 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;
|
ret = class;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -606,9 +606,10 @@ ObjectClass *object_class_dynamic_cast_assert(struct uc_struct *uc, ObjectClass
|
||||||
#ifdef CONFIG_QOM_CAST_DEBUG
|
#ifdef CONFIG_QOM_CAST_DEBUG
|
||||||
if (class && ret == class) {
|
if (class && ret == class) {
|
||||||
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
|
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:
|
out:
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue