@@ -1684,6 +1684,7 @@ static void _execute(id<MTLComputeCommandEncoder> encoder, const MetalBackend::C
16841684 std::mutex pLock;
16851685 MNNMetalContext* pContext;
16861686 id <MTLDevice > pDevice;
1687+ size_t runtimeCount = 0 ;
16871688};
16881689static MetalContext* gContext = nullptr ;
16891690MetalRuntime* MetalRuntime::create (const Backend::Info& info) {
@@ -1711,6 +1712,7 @@ static void _execute(id<MTLComputeCommandEncoder> encoder, const MetalBackend::C
17111712 }
17121713 auto mContext = (__bridge_retained void *)(gContext ->pContext );
17131714 auto rt = new MetalRuntime (mContext );
1715+ ++gContext ->runtimeCount ;
17141716 rt->setGpuMode (info.gpuMode );
17151717 if (nil != sharedContext.queue ) {
17161718 rt->setCommandQueue (sharedContext.queue , true );
@@ -1795,6 +1797,11 @@ static void _execute(id<MTLComputeCommandEncoder> encoder, const MetalBackend::C
17951797}
17961798
17971799MetalRuntime::~ MetalRuntime() {
1800+ {
1801+ std::unique_lock<std::mutex> _l (gContext ->pLock );
1802+ MNN_ASSERT (gContext ->runtimeCount > 0 );
1803+ --gContext ->runtimeCount ;
1804+ }
17981805 if (mContext ) {
17991806 CFRelease (mContext );
18001807 }
@@ -2098,6 +2105,19 @@ virtual void onRelease(MemChunk chunk) override {
20982105 id <MTLDevice > mDevice ;
20992106};
21002107
2108+ static int releaseMetalContext () {
2109+ if (gContext == nullptr ) {
2110+ return 0 ;
2111+ }
2112+ std::unique_lock<std::mutex> lock (gContext ->pLock );
2113+ if (gContext ->runtimeCount != 0 ) {
2114+ return 1 ;
2115+ }
2116+ gContext ->pContext = nil ;
2117+ gContext ->pDevice = nil ;
2118+ return 0 ;
2119+ }
2120+
21012121void registerMetalRuntimeCreator () {
21022122 // according to
21032123 // https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/HardwareGPUInformation/HardwareGPUInformation.html
@@ -2117,6 +2137,10 @@ void registerMetalRuntimeCreator() {
21172137 }
21182138}
21192139} // namespace MNN
2140+
2141+ extern " C" int MNNMetalReleaseContext (void ) {
2142+ return MNN::releaseMetalContext ();
2143+ }
21202144#else
21212145namespace MNN {
21222146void registerMetalRuntimeCreator () {
@@ -2125,5 +2149,8 @@ void registerMetalRuntimeCreator() {
21252149int MNNMetalGetTensorContent (MNNMetalTensorContent* content, void * tensor) {
21262150 return -1 ;
21272151}
2152+ extern " C" int MNNMetalReleaseContext (void ) {
2153+ return 0 ;
2154+ }
21282155
21292156#endif
0 commit comments