LCOV - code coverage report
Current view: top level - muse/framework/audio/common - audioworkgroup.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 13 13
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-CLA-applies
       4              :  *
       5              :  * MuseScore
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2026 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #pragma once
      23              : 
      24              : #include <cassert>
      25              : #include <cstddef>
      26              : #include <memory>
      27              : #include <thread>
      28              : #include <utility>
      29              : 
      30              : #include "global/functional/inplace_function_mv.h"
      31              : 
      32              : namespace muse::audio {
      33              : class AudioWorkgroupTokenProvider;
      34              : 
      35              : using ErasedAudioWorkgroupTokenProvider = muse::functional::MoveOnlyInplaceFunction<const AudioWorkgroupTokenProvider* (), 64>;
      36              : 
      37              : class AudioWorkgroupToken
      38              : {
      39              : public:
      40           48 :     AudioWorkgroupToken() = default;
      41              :     AudioWorkgroupToken(const AudioWorkgroupToken&) = delete;
      42              :     AudioWorkgroupToken& operator=(const AudioWorkgroupToken&) = delete;
      43              :     AudioWorkgroupToken(AudioWorkgroupToken&& other) noexcept
      44              :     {
      45              :         moveFrom(std::move(other));
      46              :     }
      47              : 
      48              :     AudioWorkgroupToken& operator=(AudioWorkgroupToken&& other) noexcept
      49              :     {
      50              :         if (this != &other) {
      51              :             reset();
      52              :             moveFrom(std::move(other));
      53              :         }
      54              : 
      55              :         return *this;
      56              :     }
      57              : 
      58           46 :     ~AudioWorkgroupToken()
      59              :     {
      60           46 :         reset();
      61           47 :     }
      62              : 
      63              : private:
      64              :     friend class AudioWorkGroup;
      65              : 
      66              :     explicit AudioWorkgroupToken(ErasedAudioWorkgroupTokenProvider provider)
      67              :     {
      68              :         setProvider(std::move(provider));
      69              :     }
      70              : 
      71              :     const AudioWorkgroupTokenProvider* provider() const
      72              :     {
      73              :         assertCurrentThread();
      74              :         return m_provider ? m_provider() : nullptr;
      75              :     }
      76              : 
      77              :     void setProvider(ErasedAudioWorkgroupTokenProvider workgroup)
      78              :     {
      79              :         reset();
      80              :         m_provider = std::move(workgroup);
      81              :         if (m_provider) {
      82              :             m_threadId = std::this_thread::get_id();
      83              :         }
      84              :     }
      85              : 
      86           46 :     void reset()
      87              :     {
      88           46 :         assertCurrentThread();
      89           47 :         m_provider = nullptr;
      90           46 :         m_threadId = {};
      91           47 :     }
      92              : 
      93              :     void moveFrom(AudioWorkgroupToken&& other) noexcept
      94              :     {
      95              :         other.assertCurrentThread();
      96              :         m_provider = std::move(other.m_provider);
      97              :         m_threadId = other.m_threadId;
      98              :         other.m_threadId = {};
      99              :     }
     100              : 
     101           46 :     void assertCurrentThread() const
     102              :     {
     103           46 :         assert((!m_provider || m_threadId == std::this_thread::get_id())
     104              :                && "AudioWorkgroupToken must be used on the thread that joined the audio workgroup");
     105           47 :     }
     106              : 
     107              :     ErasedAudioWorkgroupTokenProvider m_provider;
     108              :     std::thread::id m_threadId;
     109              : };
     110              : 
     111              : class AudioWorkgroupProvider;
     112              : 
     113              : class AudioWorkGroup
     114              : {
     115              : public:
     116              :     AudioWorkGroup();
     117              :     AudioWorkGroup(const AudioWorkGroup&);
     118              :     AudioWorkGroup(AudioWorkGroup&&) noexcept;
     119              :     AudioWorkGroup& operator=(const AudioWorkGroup&);
     120              :     AudioWorkGroup& operator=(AudioWorkGroup&&) noexcept;
     121              :     ~AudioWorkGroup();
     122              : 
     123              :     bool join(AudioWorkgroupToken& token);
     124              : 
     125           51 :     const AudioWorkgroupProvider* getProvider() const { return m_provider.get(); }
     126              : 
     127              :     size_t getMaxParallelThreadCount() const;
     128              : 
     129              : private:
     130              :     friend class AudioWorkgroupProvider;
     131              :     friend AudioWorkGroup makeAudioWorkgroup(void* opaqueHandle);
     132              : 
     133              :     explicit AudioWorkGroup(std::unique_ptr<AudioWorkgroupProvider> provider);
     134              : 
     135              :     static const AudioWorkgroupTokenProvider* providerFor(const AudioWorkgroupToken& token) { return token.provider(); }
     136              :     static void setProviderFor(AudioWorkgroupToken& token, ErasedAudioWorkgroupTokenProvider provider)
     137              :     {
     138              :         token.setProvider(std::move(provider));
     139              :     }
     140              : 
     141              :     static void resetProviderFor(AudioWorkgroupToken& token) { token.reset(); }
     142              : 
     143              :     std::unique_ptr<AudioWorkgroupProvider> m_provider;
     144              : };
     145              : 
     146              : AudioWorkGroup makeAudioWorkgroup(void* opaqueHandle);
     147              : } // namespace muse::audio
        

Generated by: LCOV version 2.0-1