From 1c847dd4215d60c36443985778adfe4aba96f7c6 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 22 Mar 2011 15:23:39 +0000 Subject: [PATCH] fix a memleak and quiet some warnings git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7394 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 113 ++++++++---------- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h | 65 ++++++++-- Source/Core/Core/Src/OnFrame.cpp | 2 +- .../Core/VideoCommon/Src/TextureDecoder.cpp | 2 +- 4 files changed, 106 insertions(+), 76 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index 314b3bfe5a..c641b92c17 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -111,47 +111,24 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p) p.Do(m_HCIEndpoint); p.Do(m_ACLEndpoint); p.Do(m_last_ticks); + m_acl_pool.DoState(p); - u32 size; - if (p.GetMode() == PointerWrap::MODE_READ) + if (p.GetMode() == PointerWrap::MODE_READ && + SConfig::GetInstance().m_WiimoteReconnectOnLoad) { - u8 buf[sizeof(ACLQ)]; - p.Do(size); - while (!m_ACLQ.empty()) - m_ACLQ.pop(); - for (u32 i = 0; i < size; i++) - { - p.DoVoid((void *)buf, sizeof(ACLQ)); - m_ACLQ.push(*(ACLQ *)buf); - } - if (SConfig::GetInstance().m_WiimoteReconnectOnLoad) - { - // Reset the connection of all connected wiimotes - for (unsigned int i = 0; i < 4; i++) - { - if (m_WiiMotes[i].IsConnected()) - { - m_WiiMotes[i].Activate(false); - m_WiiMotes[i].Activate(true); - } - else - { - m_WiiMotes[i].Activate(false); - } - } - } - } - else - { - size = m_ACLQ.size(); - p.Do(size); - for (u32 i = 0; i < size; i++) - { - ACLQ tmp = m_ACLQ.front(); - m_ACLQ.pop(); - m_ACLQ.push(tmp); - p.DoVoid((void *)&tmp, sizeof(ACLQ)); - } + // Reset the connection of all connected wiimotes + for (unsigned int i = 0; i < 4; i++) + { + if (m_WiiMotes[i].IsConnected()) + { + m_WiiMotes[i].Activate(false); + m_WiiMotes[i].Activate(true); + } + else + { + m_WiiMotes[i].Activate(false); + } + } } } @@ -361,10 +338,10 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::IncDataPacket(u16 _ConnectionHandle) { m_PacketCount[_ConnectionHandle & 0xff]++; - if (m_PacketCount[_ConnectionHandle & 0xff] > 10) + if (m_PacketCount[_ConnectionHandle & 0xff] > m_acl_pkts_num) { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL buffer overflow"); - m_PacketCount[_ConnectionHandle & 0xff] = 10; + m_PacketCount[_ConnectionHandle & 0xff] = m_acl_pkts_num; } } @@ -390,8 +367,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u else { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint not currently valid, " - "queueing(%lu)...", (unsigned long)m_ACLQ.size()); - m_ACLQ.push(ACLQ(_pData, _Size, _ConnectionHandle)); + "queueing(%lu)...", m_acl_pool.GetWritePos()); + m_acl_pool.Store(_pData, _Size, _ConnectionHandle); } } @@ -446,6 +423,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _e u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() { bool packet_transferred = false; + // check hci queue if (!m_EventQueue.empty() && m_HCIEndpoint.IsValid()) { @@ -466,25 +444,9 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() } // check acl queue - // We give priority to HCI events, so ACL data won't be sent to host if HCI event queue contains events. - if (!m_ACLQ.empty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty()) + if (!m_acl_pool.IsEmpty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty()) { - const ACLQ& acl_data = m_ACLQ.front(); - DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from " - "queue(%lu) to %08x", (unsigned long)m_ACLQ.size()-1, - m_ACLEndpoint.m_address); - - hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(m_ACLEndpoint.m_buffer); - pHeader->con_handle = HCI_MK_CON_HANDLE(acl_data.m_conn_handle, HCI_PACKET_START, HCI_POINT2POINT); - pHeader->length = acl_data.m_size; - - // Write the packet to the buffer - memcpy((u8*)pHeader + sizeof(hci_acldata_hdr_t), acl_data.m_buffer, pHeader->length); - - m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + acl_data.m_size); - WII_IPC_HLE_Interface::EnqReply(m_ACLEndpoint.m_address); - m_ACLEndpoint.Invalidate(); - m_ACLQ.pop(); + m_acl_pool.WriteToEndpoint(m_ACLEndpoint); packet_transferred = true; } @@ -502,7 +464,6 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() { Host_SetWiiMoteConnectionState(1); SendEventRequestConnection(m_WiiMotes[i]); - //return true; } } } @@ -542,6 +503,30 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() return packet_transferred; } +void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::WriteToEndpoint(CtrlBuffer& endpoint) +{ + const u8 *data = m_pool + m_acl_pkt_size * m_read_ptr; + const u16 size = m_info[m_read_ptr].size; + const u16 conn_handle = m_info[m_read_ptr].conn_handle; + + DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from " + "queue(%lu) to %08x", GetReadPos(), endpoint.m_address); + + hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_buffer); + pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT); + pHeader->length = size; + + // Write the packet to the buffer + memcpy((u8*)pHeader + sizeof(hci_acldata_hdr_t), data, pHeader->length); + + endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); + + m_read_ptr = (m_read_ptr + 1) % m_acl_pkts_num; + + WII_IPC_HLE_Interface::EnqReply(endpoint.m_address); + endpoint.Invalidate(); +} + bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventInquiryComplete() { SQueuedEvent Event(sizeof(SHCIEventInquiryComplete), 0); @@ -1766,11 +1751,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadBufferSize(u8* _Input) { hci_read_buffer_size_rp Reply; Reply.status = 0x00; - Reply.max_acl_size = 339; + Reply.max_acl_size = m_acl_pkt_size; // Due to how the widcomm stack which nintendo uses is coded, we must never // let the stack think the controller is buffering more than 10 data packets // - it will cause a u8 underflow and royally screw things up. - Reply.num_acl_pkts = 10; + Reply.num_acl_pkts = m_acl_pkts_num; Reply.max_sco_size = 64; Reply.num_sco_pkts = 0; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h index 1ebc77b1b5..de925b2e67 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h @@ -156,19 +156,64 @@ private: u32 m_ACLSetup; CtrlBuffer m_ACLEndpoint; - struct ACLQ + + static const int m_acl_pkt_size = 339; + static const int m_acl_pkts_num = 10; + + class ACLPool { - u8* m_buffer; - size_t m_size; - u16 m_conn_handle; - ACLQ(const u8* data, const size_t size, const u16 conn_handle) - : m_size(size), m_conn_handle(conn_handle) + u8 m_pool[m_acl_pkt_size * m_acl_pkts_num]; + int m_read_ptr; + int m_write_ptr; + + struct { - m_buffer = new u8[m_size]; // TODO: memleak - memcpy(m_buffer, data, m_size); + u16 size; + u16 conn_handle; + } m_info[m_acl_pkts_num]; + + public: + ACLPool() + : m_read_ptr(0) + , m_write_ptr(0) + {} + + void Store(const u8* data, const u16 size, const u16 conn_handle) + { + _dbg_assert_msg_(WII_IPC_WIIMOTE, + size < m_acl_pkt_size, "acl packet too large for pool"); + memcpy(m_pool + m_acl_pkt_size * m_write_ptr, data, size); + m_info[m_write_ptr].size = size; + m_info[m_write_ptr].conn_handle = conn_handle; + m_write_ptr = (m_write_ptr + 1) % m_acl_pkts_num; } - }; - std::queue m_ACLQ; + + void WriteToEndpoint(CtrlBuffer& endpoint); + + bool IsEmpty() const + { + return m_write_ptr == m_read_ptr; + } + + int GetWritePos() const + { + return m_write_ptr; + } + + int GetReadPos() const + { + return m_read_ptr; + } + + // For SaveStates + void DoState(PointerWrap &p) + { + p.Do(m_write_ptr); + p.Do(m_read_ptr); + p.DoArray(m_pool, sizeof(m_pool)); + p.DoArray(m_info, sizeof(m_info)); + } + } m_acl_pool; u32 m_PacketCount[4]; u64 m_last_ticks; diff --git a/Source/Core/Core/Src/OnFrame.cpp b/Source/Core/Core/Src/OnFrame.cpp index 032eb88f4e..c58ba9ccc8 100644 --- a/Source/Core/Core/Src/OnFrame.cpp +++ b/Source/Core/Core/Src/OnFrame.cpp @@ -585,7 +585,7 @@ void EndPlayInput(bool cont) void SaveRecording(const char *filename) { - const off_t size = g_recordfd.Tell(); + const u64 size = g_recordfd.Tell(); // NOTE: Eventually this will not happen in // read-only mode, but we need a way for the save state to diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/TextureDecoder.cpp index 3399d5f429..180c901730 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/TextureDecoder.cpp @@ -30,7 +30,7 @@ #ifdef _OPENMP #include -#else +#elif defined __GNUC__ #pragma GCC diagnostic ignored "-Wunknown-pragmas" #endif