Я включил средство очистки потока в Xcode 9.4.1, и теперь я получаю предупреждение о нечетном состоянии гонки на моем вращающемся буфере (размером до 2).Я бы подумал, что правильное использование семафора устранит эту проблему.Я должен упомянуть, что этот буфер получается из результатов другого кодирования рендеринга в отдельном «первом» MTKView
.У меня есть семафор, который я инициализировал через dispatch_semaphore_create(1)
во втором нижестоящем представлении.
В моем первом MTKView
я получаю визуализированную текстуру следующим образом после того, как зафиксировал ее, а затем помещаю в очередь внисходящий буфер, использующий семафор этого нисходящего представления:
[commandBuffer presentDrawable:self.currentDrawable];
[commandBuffer commit];
//[commandBuffer waitUntilCompleted]; // (doesn't matter if this is in or out)
...
id obj = [self.renderedQueue firstObject];
for (MonitorMTKView *v in self.downstreamOutputs) {
dispatch_semaphore_wait(v.bufferSemaphore,DISPATCH_TIME_FOREVER);
[v.textureQueue addObject:inputTexture];
if ([v.textureQueue count]>2)
[v.textureQueue removeObjectAtIndex:0];
dispatch_semaphore_signal(v.bufferSemaphore);
}
Теперь в цикле рендеринга в моем нисходящем MTKView
.Я фиксирую командный буфер, и у меня есть этот обработчик завершения:
__block __weak __typeof__(self) weakSelf = self;
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
dispatch_semaphore_wait(weakSelf.bufferSemaphore, DISPATCH_TIME_FOREVER);
id obj = [weakSelf.textureQueue firstObject];
**// thread sanitizer issue on this next line of code "Race on a library object detected" **
[weakSelf.textureQueue removeObject:obj];
dispatch_semaphore_signal(weakSelf.bufferSemaphore);
}
Почему условие гонки вокруг того, что защищено семафором? Есть что-то, что я делаю ужасно неправильно? .Сам по себе буфер не основан на графическом процессоре, поэтому там не может быть помех.
Одно из соображений состоит в том, чтобы трижды буферизовать это, но это не облегчает проблему, поэтому я не будудумаю, что его помехи GPU.