Use Mutex to control writes to the RX_Frame counter

A user on http://obsrv.org had an issue with freezing, unfreezing than
dying on other players screen, but can continue playing anyway. This
comment didn't end up fixing the issue of becoming a ghost, but he
didn't freeze.
This commit is contained in:
TheLastRar 2015-05-28 20:22:38 +01:00
parent ff4cf51494
commit 66b08c0b2f
1 changed files with 19 additions and 2 deletions

View File

@ -23,6 +23,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <windows.h> #include <windows.h>
#include <stdarg.h> #include <stdarg.h>
#include <mutex>
#include "smap.h" #include "smap.h"
#include "net.h" #include "net.h"
@ -31,6 +32,9 @@
#include "tap.h" #include "tap.h"
bool has_link=true; bool has_link=true;
volatile bool fireIntR = false;
std::mutex frame_counter_mutex;
std::mutex reset_mutex;
/* /*
#define SMAP_BASE 0xb0000000 #define SMAP_BASE 0xb0000000
#define SMAP_REG8(Offset) (*(u8 volatile*)(SMAP_BASE+(Offset))) #define SMAP_REG8(Offset) (*(u8 volatile*)(SMAP_BASE+(Offset)))
@ -81,7 +85,7 @@ bool rx_fifo_can_rx()
//we can recv a packet ! //we can recv a packet !
return true; return true;
} }
volatile bool fireIntR = false;
void rx_process(NetPacket* pk) void rx_process(NetPacket* pk)
{ {
if (!rx_fifo_can_rx()) if (!rx_fifo_can_rx())
@ -108,6 +112,7 @@ void rx_process(NetPacket* pk)
} }
//increase RXBD //increase RXBD
std::unique_lock<std::mutex> reset_lock(reset_mutex);
dev9.rxbdi++; dev9.rxbdi++;
dev9.rxbdi&=(SMAP_BD_SIZE/8)-1; dev9.rxbdi&=(SMAP_BD_SIZE/8)-1;
@ -117,7 +122,10 @@ void rx_process(NetPacket* pk)
pbd->ctrl_stat&= ~SMAP_BD_RX_EMPTY; pbd->ctrl_stat&= ~SMAP_BD_RX_EMPTY;
//increase frame count //increase frame count
std::unique_lock<std::mutex> counter_lock(frame_counter_mutex);
dev9Ru8(SMAP_R_RXFIFO_FRAME_CNT)++; dev9Ru8(SMAP_R_RXFIFO_FRAME_CNT)++;
counter_lock.unlock();
reset_lock.unlock();
//spams// emu_printf("Got packet, %d bytes (%d fifo)\n", pk->size,bytes); //spams// emu_printf("Got packet, %d bytes (%d fifo)\n", pk->size,bytes);
fireIntR = true; fireIntR = true;
//_DEV9irq(SMAP_INTR_RXEND,0);//now ? or when the fifo is full ? i guess now atm //_DEV9irq(SMAP_INTR_RXEND,0);//now ? or when the fifo is full ? i guess now atm
@ -530,6 +538,8 @@ u32 CALLBACK smap_read32(u32 addr)
} }
void CALLBACK smap_write8(u32 addr, u8 value) void CALLBACK smap_write8(u32 addr, u8 value)
{ {
std::unique_lock<std::mutex> reset_lock(reset_mutex, std::defer_lock);
std::unique_lock<std::mutex> counter_lock(frame_counter_mutex, std::defer_lock);
switch(addr) switch(addr)
{ {
case SMAP_R_TXFIFO_FRAME_INC: case SMAP_R_TXFIFO_FRAME_INC:
@ -541,10 +551,12 @@ void CALLBACK smap_write8(u32 addr, u8 value)
case SMAP_R_RXFIFO_FRAME_DEC: case SMAP_R_RXFIFO_FRAME_DEC:
DEV9_LOG("SMAP_R_RXFIFO_FRAME_DEC 8bit write %x\n", value); DEV9_LOG("SMAP_R_RXFIFO_FRAME_DEC 8bit write %x\n", value);
counter_lock.lock();
dev9Ru8(addr) = value; dev9Ru8(addr) = value;
{ {
dev9Ru8(SMAP_R_RXFIFO_FRAME_CNT)--; dev9Ru8(SMAP_R_RXFIFO_FRAME_CNT)--;
} }
counter_lock.unlock();
return; return;
case SMAP_R_TXFIFO_CTRL: case SMAP_R_TXFIFO_CTRL:
@ -565,11 +577,15 @@ void CALLBACK smap_write8(u32 addr, u8 value)
DEV9_LOG("SMAP_R_RXFIFO_CTRL 8bit write %x\n", value); DEV9_LOG("SMAP_R_RXFIFO_CTRL 8bit write %x\n", value);
if(value&SMAP_RXFIFO_RESET) if(value&SMAP_RXFIFO_RESET)
{ {
reset_lock.lock(); //lock reset mutex 1st
counter_lock.lock();
dev9.rxbdi=0; dev9.rxbdi=0;
dev9.rxfifo_wr_ptr=0; dev9.rxfifo_wr_ptr=0;
dev9Ru8(SMAP_R_RXFIFO_FRAME_CNT)=0; dev9Ru8(SMAP_R_RXFIFO_FRAME_CNT)=0;
dev9Ru32(SMAP_R_RXFIFO_RD_PTR)=0; dev9Ru32(SMAP_R_RXFIFO_RD_PTR)=0;
dev9Ru32(SMAP_R_RXFIFO_SIZE)=16384; dev9Ru32(SMAP_R_RXFIFO_SIZE)=16384;
reset_lock.unlock();
counter_lock.unlock();
} }
value&= ~SMAP_RXFIFO_RESET; value&= ~SMAP_RXFIFO_RESET;
dev9Ru8(addr) = value; dev9Ru8(addr) = value;
@ -846,8 +862,9 @@ void CALLBACK smap_async(u32 cycles)
{ {
if (fireIntR) if (fireIntR)
{ {
fireIntR = false; //Thread unsafe? fireIntR = false;
//Is this used to signal each individual packet, or just when there are packets in the RX fifo? //Is this used to signal each individual packet, or just when there are packets in the RX fifo?
//I think it just signals when there are packets in the RX fifo
_DEV9irq(SMAP_INTR_RXEND, 0); //Make the call to _DEV9irq in a thread safe way _DEV9irq(SMAP_INTR_RXEND, 0); //Make the call to _DEV9irq in a thread safe way
} }
} }