ST77xx memory corruption + mp3 sync using library + mutex for poll in stream() - release

This commit is contained in:
Philippe G
2020-08-29 22:07:07 -07:00
parent ce369638da
commit 7e097a7ee9
5 changed files with 42 additions and 15 deletions

Binary file not shown.

View File

@@ -90,7 +90,7 @@ static void Update16( struct GDS_Device* Device ) {
for (int i = FirstRow; i <= LastRow; i++) { for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize); memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 2, ChunkSize);
optr += ChunkSize; optr += ChunkSize;
if (optr - Private->iRAM < PAGE_BLOCK && i < LastRow) continue; if (optr - Private->iRAM <= (PAGE_BLOCK - ChunkSize) && i < LastRow) continue;
Device->WriteData(Device, Private->iRAM, optr - Private->iRAM); Device->WriteData(Device, Private->iRAM, optr - Private->iRAM);
optr = Private->iRAM; optr = Private->iRAM;
} }
@@ -157,7 +157,7 @@ static void Update24( struct GDS_Device* Device ) {
for (int i = FirstRow; i <= LastRow; i++) { for (int i = FirstRow; i <= LastRow; i++) {
memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 3, ChunkSize); memcpy(optr, Private->Shadowbuffer + (i * Device->Width + FirstCol) * 3, ChunkSize);
optr += ChunkSize; optr += ChunkSize;
if (optr - Private->iRAM < PAGE_BLOCK && i < LastRow) continue; if (optr - Private->iRAM <= (PAGE_BLOCK - ChunkSize) && i < LastRow) continue;
Device->WriteData(Device, Private->iRAM, optr - Private->iRAM); Device->WriteData(Device, Private->iRAM, optr - Private->iRAM);
optr = Private->iRAM; optr = Private->iRAM;
} }

View File

@@ -628,8 +628,9 @@ static void grfe_handler( u8_t *data, int len) {
scroller.active = false; scroller.active = false;
// visu has priority when full screen on small screens // full screen artwork or for small screen, full screen visu has priority
if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) { if (((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) ||
(artwork.enable && artwork.x == 0 && artwork.y == 0)) {
xSemaphoreGive(displayer.mutex); xSemaphoreGive(displayer.mutex);
return; return;
} }
@@ -751,8 +752,11 @@ static void grfg_handler(u8_t *data, int len) {
LOG_DEBUG("gfrg s:%hu w:%hu (len:%u)", htons(pkt->screen), htons(pkt->width), len); LOG_DEBUG("gfrg s:%hu w:%hu (len:%u)", htons(pkt->screen), htons(pkt->width), len);
// on small screen, visu has priority when full screen // full screen artwork or for small screen, visu has priority when full screen
if ((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) return; if (((visu.mode & VISU_ESP32) && !visu.col && visu.row < displayer.height) ||
(artwork.enable && artwork.x == 0 && artwork.y == 0)) {
return;
}
xSemaphoreTake(displayer.mutex, portMAX_DELAY); xSemaphoreTake(displayer.mutex, portMAX_DELAY);
@@ -840,8 +844,10 @@ static void grfa_handler(u8_t *data, int len) {
* Update visualization bars * Update visualization bars
*/ */
static void visu_update(void) { static void visu_update(void) {
// no need to protect against no woning the display as we are playing // no update when artwork is full screen (but no need to protect against not owning the display as we are playing
if (pthread_mutex_trylock(&visu_export.mutex)) return; if ((artwork.enable && artwork.x == 0 && artwork.y == 0) || pthread_mutex_trylock(&visu_export.mutex)) {
return;
}
int mode = visu.mode & ~VISU_ESP32; int mode = visu.mode & ~VISU_ESP32;

View File

@@ -243,8 +243,6 @@ static decode_state mad_decode(void) {
MAD(m, synth_frame, &m->synth, &m->frame); MAD(m, synth_frame, &m->synth, &m->frame);
if (decode.new_stream) { if (decode.new_stream) {
// seems that mad can use some help in term of sync detection
if (m->stream.next_frame[0] != 0xff || (m->stream.next_frame[1] & 0xf0) != 0xf0) continue;
LOCK_O; LOCK_O;
LOG_INFO("setting track_start"); LOG_INFO("setting track_start");
output.next_sample_rate = decode_newstream(m->synth.pcm.samplerate, output.supported_rates); output.next_sample_rate = decode_newstream(m->synth.pcm.samplerate, output.supported_rates);

View File

@@ -40,13 +40,32 @@
static log_level loglevel; static log_level loglevel;
static struct buffer buf; static struct buffer buf;
static mutex_type poll_mutex;
struct buffer *streambuf = &buf; struct buffer *streambuf = &buf;
#define LOCK mutex_lock(streambuf->mutex) #define LOCK mutex_lock(streambuf->mutex)
#define UNLOCK mutex_unlock(streambuf->mutex) #define UNLOCK mutex_unlock(streambuf->mutex)
/*
After a lot of hesitation, I've added that "poll mutex" to prevent
socket from being allocated while we are still in poll(). The issue
happens is we have a close quickly followed by an open, we might still
be in the poll() and simple OS fail as they re-allocate the same socket
on which a thread is still waiting.
Ideally, you want to set the lock in the disconnect() but that would mean
very often we'd have to always wait for the end of the poll(), i.e. up to
100ms for nothing most of the time where if it is in the open(), it is
less elegant as closing a socket on which there is a poll() is not good
but it's more efficient as it is very rare that you'd have an open() less
then 100ms after a close()
*/
#if EMBEDDED
static mutex_type poll_mutex;
#define LOCK_L mutex_lock(poll_mutex) #define LOCK_L mutex_lock(poll_mutex)
#define UNLOCK_L mutex_unlock(poll_mutex) #define UNLOCK_L mutex_unlock(poll_mutex)
#else
#define LOCK_L
#define UNLOCK_L
#endif
static sockfd fd; static sockfd fd;
@@ -408,7 +427,9 @@ void stream_init(log_level level, unsigned stream_buf_size) {
*stream.header = '\0'; *stream.header = '\0';
fd = -1; fd = -1;
#if EMBEDDED
mutex_create_p(poll_mutex); mutex_create_p(poll_mutex);
#endif
#if LINUX || FREEBSD #if LINUX || FREEBSD
touch_memory(streambuf->buf, streambuf->size); touch_memory(streambuf->buf, streambuf->size);
@@ -438,7 +459,9 @@ void stream_close(void) {
#endif #endif
free(stream.header); free(stream.header);
buf_destroy(streambuf); buf_destroy(streambuf);
#if EMBEDDED
mutex_destroy(poll_mutex); mutex_destroy(poll_mutex);
#endif
} }
void stream_file(const char *header, size_t header_len, unsigned threshold) { void stream_file(const char *header, size_t header_len, unsigned threshold) {
@@ -480,7 +503,9 @@ void stream_file(const char *header, size_t header_len, unsigned threshold) {
void stream_sock(u32_t ip, u16_t port, const char *header, size_t header_len, unsigned threshold, bool cont_wait) { void stream_sock(u32_t ip, u16_t port, const char *header, size_t header_len, unsigned threshold, bool cont_wait) {
struct sockaddr_in addr; struct sockaddr_in addr;
LOCK_L;
int sock = socket(AF_INET, SOCK_STREAM, 0); int sock = socket(AF_INET, SOCK_STREAM, 0);
UNLOCK_L;
if (sock < 0) { if (sock < 0) {
LOG_ERROR("failed to create socket"); LOG_ERROR("failed to create socket");
@@ -588,13 +613,11 @@ bool stream_disconnect(void) {
ssl = NULL; ssl = NULL;
} }
#endif #endif
LOCK_L;
if (fd != -1) { if (fd != -1) {
closesocket(fd); closesocket(fd);
fd = -1; fd = -1;
disc = true; disc = true;
} }
UNLOCK_L,
stream.state = STOPPED; stream.state = STOPPED;
UNLOCK; UNLOCK;
return disc; return disc;