MTKTextureLoader hangs in a semphore wait

So, using the basics from Metal by Tutorials I built an app which renders of number of cube meshes, each face with a different texture mapped image. I increase the number of cubes and, eventually, MTKTextureLoader hangs in a semaphore wait after a random number of texture loads. I’ve included the basic texture loading code and, when it hung, I stopped the app and took a look at the assembler where the hang occurs. I did step along, and it just looped in some system semaphore wait code (I know this code isn’t very informative).

So, questions are
- any idea what semaphore I’m waiting on?
- is there something that needs to be done between/during loader.newTexture calls to clear the semaphore (like, what could be causing the collision)?
- is there some debug to find out who owns this semaphore?

Thanks in advance for any clues.

static func loadTexture(fileName: String) -> MTLTexture? {
    let loader = MTKTextureLoader(device: Renderer.Device)
    let texture: MTLTexture?
    var url:URL
    url = URL(fileURLWithPath: fileName)
    let loaderOptions : [MTKTextureLoader.Option: Any] =
                        [.origin:MTKTextureLoader.Origin.bottomLeft,
                         .allocateMipmaps: false,
                         .generateMipmaps: false]
    texture = try? loader.newTexture(URL:url,options:loaderOptions)
}


    0x19d2ec528 <+228>: add    x10, x10, #0x130          ; __block_descriptor_56_e8_32o40r48r_e34_v24^A?0^A"<MTLTexture>"8^A"NSError"16l
    0x19d2ec52c <+232>: stp    x16, x10, [sp, #0x18]
    0x19d2ec530 <+236>: stp    x8, x9, [sp, #0x30]
    0x19d2ec534 <+240>: str    x0, [sp, #0x28]
    0x19d2ec538 <+244>: add    x4, sp, #0x8
    0x19d2ec53c <+248>: mov    x0, x23
    0x19d2ec540 <+252>: mov    x2, x22
    0x19d2ec544 <+256>: mov    x3, x21
    0x19d2ec548 <+260>: bl     0x19d302160               ; objc_msgSend$newTextureWithContentsOfURL:options:completionHandler:
    0x19d2ec54c <+264>: mov    x0, x20
    0x19d2ec550 <+268>: mov    x1, #-0x1                 ; =-1
    0x19d2ec554 <+272>: bl     0x19d2f8690               ; symbol stub for: dispatch_semaphore_wait
->  0x19d2ec558 <+276>: mov    x0, x20
    0x19d2ec55c <+280>: bl     0x19d2f8640               ; symbol stub for: dispatch_release
    0x19d2ec560 <+284>: cbz    x19, 0x19d2ec574          ; <+304>
    0x19d2ec564 <+288>: ldr    x8, [sp, #0x48]
    0x19d2ec568 <+292>: ldr    x0, [x8, #0x28]
    0x19d2ec56c <+296>: bl     0x19d2f8780               ; symbol stub for: objc_autorelease
    0x19d2ec570 <+300>: str    x0, [x19]
    0x19d2ec574 <+304>: ldur   x8, [x29, #-0x58]



I figured it out.
A while back I had implemented code to load textures in a separate thread and, since it “worked”, I promptly forgot about it. So, MUCH later, I finally hit this hang. Turns out, after a bunch of debug (and actually READING the documentation), newTexture:url without a completion handler is synchronous. Ooops. Fixed my race condition and looks like it “works” again (we’ll see…)
Sorry to take up any time of anyone spent looking at this.

2 Likes