comparison event_log.c @ 2686:05915f01046d

WIP attempt to move VDP rendering to a separate thread
author Michael Pavone <pavone@retrodev.com>
date Mon, 31 Mar 2025 21:02:17 -0700
parents c4256ce2c45a
children
comparison
equal deleted inserted replaced
2685:da2e06c42d16 2686:05915f01046d
7 #include <sys/socket.h> 7 #include <sys/socket.h>
8 #include <unistd.h> 8 #include <unistd.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <netinet/in.h> 10 #include <netinet/in.h>
11 #include <netinet/tcp.h> 11 #include <netinet/tcp.h>
12 #include <pthread.h>
12 #endif 13 #endif
13 14
14 #include <stdlib.h> 15 #include <stdlib.h>
15 #include <string.h> 16 #include <string.h>
16 #include <errno.h> 17 #include <errno.h>
125 event_log_common_init(); 126 event_log_common_init();
126 cleanup_address: 127 cleanup_address:
127 freeaddrinfo(result); 128 freeaddrinfo(result);
128 } 129 }
129 130
131 static event_reader *mem_reader;
132 static uint8_t mem_reader_quit = 1;
133 #ifndef _WIN32
134 void event_log_mem(void)
135 {
136 event_log_common_init();
137 free(buffer.data);
138 buffer.storage = 1024 * 1024;
139 buffer.data = malloc(buffer.storage);
140 mem_reader = calloc(1, sizeof(event_reader));
141 mem_reader->last_cycle = 0;
142 mem_reader->repeat_event = 0xFF;
143 mem_reader->storage = buffer.storage;
144 init_deserialize(&mem_reader->buffer, buffer.data, 0);
145 mem_reader_quit = 0;
146 }
147 #endif
148
130 static uint8_t *system_start; 149 static uint8_t *system_start;
131 static size_t system_start_size; 150 static size_t system_start_size;
132 void event_system_start(system_type stype, vid_std video_std, char *name) 151 void event_system_start(system_type stype, vid_std video_std, char *name)
133 { 152 {
134 if (!active) { 153 if (!active || mem_reader) {
135 return; 154 return;
136 } 155 }
137 save_int8(&buffer, stype); 156 save_int8(&buffer, stype);
138 save_int8(&buffer, video_std); 157 save_int8(&buffer, video_std);
139 size_t name_len = strlen(name); 158 size_t name_len = strlen(name);
200 } 219 }
201 } 220 }
202 221
203 void event_cycle_adjust(uint32_t cycle, uint32_t deduction) 222 void event_cycle_adjust(uint32_t cycle, uint32_t deduction)
204 { 223 {
205 if (!fully_active) { 224 if (!fully_active && !mem_reader) {
206 return; 225 return;
207 } 226 }
208 event_header(EVENT_ADJUST, cycle); 227 event_header(EVENT_ADJUST, cycle);
209 last = cycle - deduction; 228 last = cycle - deduction;
210 save_int32(&buffer, deduction); 229 save_int32(&buffer, deduction);
320 } 339 }
321 } 340 }
322 } 341 }
323 } 342 }
324 343
344 #ifndef _WIN32
345 static pthread_mutex_t event_log_lock = PTHREAD_MUTEX_INITIALIZER;
346 static pthread_cond_t event_cond = PTHREAD_COND_INITIALIZER;
347 #endif
348 static event_reader *mem_reader;
325 uint8_t wrote_since_last_flush; 349 uint8_t wrote_since_last_flush;
326 void event_log(uint8_t type, uint32_t cycle, uint8_t size, uint8_t *payload) 350 void event_log(uint8_t type, uint32_t cycle, uint8_t size, uint8_t *payload)
327 { 351 {
328 if (!fully_active) { 352 if (!fully_active && (!mem_reader || type == EVENT_PSG_REG || type == EVENT_YM_REG)) {
329 return; 353 return;
330 } 354 }
355
331 event_header(type, cycle); 356 event_header(type, cycle);
332 last = cycle; 357 last = cycle;
333 save_buffer8(&buffer, payload, size); 358 save_buffer8(&buffer, payload, size);
334 if (!multi_count) { 359 if (!multi_count) {
335 last_event_type = 0xFF; 360 last_event_type = 0xFF;
336 output_stream.avail_in = buffer.size - (output_stream.next_in - buffer.data); 361 #ifndef _WIN32
337 int result = deflate(&output_stream, Z_NO_FLUSH); 362 if (mem_reader) {
338 if (result != Z_OK) { 363 pthread_mutex_lock(&event_log_lock);
339 fatal_error("deflate returned %d\n", result); 364 if (mem_reader->buffer.cur_pos) {
340 } 365 memmove(buffer.data, buffer.data + mem_reader->buffer.cur_pos, buffer.size - mem_reader->buffer.cur_pos);
341 if (listen_sock) { 366 buffer.size -= mem_reader->buffer.cur_pos;
342 if ((output_stream.next_out - compressed) > 1280 || !output_stream.avail_out) { 367 mem_reader->buffer.cur_pos = 0;
343 flush_socket(); 368 }
344 wrote_since_last_flush = 1; 369 mem_reader->buffer.size = buffer.size;
345 } 370 pthread_cond_signal(&event_cond);
346 } else if (!output_stream.avail_out) { 371 pthread_mutex_unlock(&event_log_lock);
347 fwrite(compressed, 1, compressed_storage, event_file); 372 } else
348 output_stream.next_out = compressed; 373 #endif
349 output_stream.avail_out = compressed_storage; 374 {
350 } 375 output_stream.avail_in = buffer.size - (output_stream.next_in - buffer.data);
351 if (!output_stream.avail_in) { 376 int result = deflate(&output_stream, Z_NO_FLUSH);
352 buffer.size = 0; 377 if (result != Z_OK) {
353 output_stream.next_in = buffer.data; 378 fatal_error("deflate returned %d\n", result);
354 } 379 }
355 } 380 if (listen_sock) {
356 } 381 if ((output_stream.next_out - compressed) > 1280 || !output_stream.avail_out) {
382 flush_socket();
383 wrote_since_last_flush = 1;
384 }
385 } else if (!output_stream.avail_out) {
386 fwrite(compressed, 1, compressed_storage, event_file);
387 output_stream.next_out = compressed;
388 output_stream.avail_out = compressed_storage;
389 }
390 if (!output_stream.avail_in) {
391 buffer.size = 0;
392 output_stream.next_in = buffer.data;
393 }
394 }
395 }
396 }
397
398 #ifndef _WIN32
399 void event_log_mem_stop(void)
400 {
401 pthread_mutex_lock(&event_log_lock);
402 mem_reader_quit = 1;
403 pthread_cond_signal(&event_cond);
404 pthread_mutex_unlock(&event_log_lock);
405 }
406 #endif
357 407
358 static uint32_t last_word_address; 408 static uint32_t last_word_address;
359 void event_vram_word(uint32_t cycle, uint32_t address, uint16_t value) 409 void event_vram_word(uint32_t cycle, uint32_t address, uint16_t value)
360 { 410 {
361 uint32_t delta = address - last_word_address; 411 uint32_t delta = address - last_word_address;
497 void event_flush(uint32_t cycle) 547 void event_flush(uint32_t cycle)
498 { 548 {
499 if (!active) { 549 if (!active) {
500 return; 550 return;
501 } 551 }
502 if (fully_active) { 552 if (fully_active || mem_reader) {
503 event_header(EVENT_FLUSH, cycle); 553 event_header(EVENT_FLUSH, cycle);
504 last = cycle; 554 last = cycle;
505 555
506 deflate_flush(0); 556 #ifndef _WIN32
557 if (mem_reader) {
558 pthread_mutex_lock(&event_log_lock);
559 if (mem_reader->buffer.cur_pos) {
560 memmove(buffer.data, buffer.data + mem_reader->buffer.cur_pos, buffer.size - mem_reader->buffer.cur_pos);
561 buffer.size -= mem_reader->buffer.cur_pos;
562 mem_reader->buffer.cur_pos = 0;
563 }
564 mem_reader->buffer.size = buffer.size;
565 pthread_cond_signal(&event_cond);
566 pthread_mutex_unlock(&event_log_lock);
567 } else
568 #endif
569 {
570 deflate_flush(0);
571 }
507 } 572 }
508 if (event_file) { 573 if (event_file) {
509 fwrite(compressed, 1, output_stream.next_out - compressed, event_file); 574 fwrite(compressed, 1, output_stream.next_out - compressed, event_file);
510 fflush(event_file); 575 fflush(event_file);
511 output_stream.next_out = compressed; 576 output_stream.next_out = compressed;
516 } 581 }
517 } 582 }
518 583
519 void event_soft_flush(uint32_t cycle) 584 void event_soft_flush(uint32_t cycle)
520 { 585 {
521 if (!fully_active || wrote_since_last_flush || event_file) { 586 if ((!fully_active && !mem_reader) || wrote_since_last_flush || event_file) {
522 return; 587 return;
523 } 588 }
524 event_header(EVENT_FLUSH, cycle); 589 event_header(EVENT_FLUSH, cycle);
525 last = cycle; 590 last = cycle;
526 591
527 deflate_flush(0); 592 #ifndef _WIN32
528 flush_socket(); 593 if (mem_reader) {
594 pthread_mutex_lock(&event_log_lock);
595 if (mem_reader->buffer.cur_pos) {
596 memmove(buffer.data, buffer.data + mem_reader->buffer.cur_pos, buffer.size - mem_reader->buffer.cur_pos);
597 buffer.size -= mem_reader->buffer.cur_pos;
598 mem_reader->buffer.cur_pos = 0;
599 }
600 mem_reader->buffer.size = buffer.size;
601 pthread_cond_signal(&event_cond);
602 pthread_mutex_unlock(&event_log_lock);
603 } else
604 #endif
605 {
606 deflate_flush(0);
607 flush_socket();
608 }
529 } 609 }
530 610
531 static void init_event_reader_common(event_reader *reader) 611 static void init_event_reader_common(event_reader *reader)
532 { 612 {
533 reader->last_cycle = 0; 613 reader->last_cycle = 0;
662 742
663 } 743 }
664 744
665 void reader_ensure_data(event_reader *reader, size_t bytes) 745 void reader_ensure_data(event_reader *reader, size_t bytes)
666 { 746 {
667 if (reader->buffer.size - reader->buffer.cur_pos < bytes) { 747 #ifndef _WIN32
668 if (reader->input_stream.avail_in) { 748 if (reader == mem_reader) {
669 inflate_flush(reader); 749 while (!mem_reader_quit && reader->buffer.size - reader->buffer.cur_pos < bytes) {
670 } 750 pthread_cond_wait(&event_cond, &event_log_lock);
671 if (reader->socket) { 751 }
672 while (reader->buffer.size - reader->buffer.cur_pos < bytes) { 752 } else
673 read_from_socket(reader); 753 #endif
754 {
755 if (reader->buffer.size - reader->buffer.cur_pos < bytes) {
756 if (reader->input_stream.avail_in) {
674 inflate_flush(reader); 757 inflate_flush(reader);
758 }
759 if (reader->socket) {
760 while (reader->buffer.size - reader->buffer.cur_pos < bytes) {
761 read_from_socket(reader);
762 inflate_flush(reader);
763 }
675 } 764 }
676 } 765 }
677 } 766 }
678 } 767 }
679 768
684 *cycle_out = reader->last_cycle + reader->repeat_delta; 773 *cycle_out = reader->last_cycle + reader->repeat_delta;
685 reader->last_cycle = *cycle_out; 774 reader->last_cycle = *cycle_out;
686 return reader->repeat_event; 775 return reader->repeat_event;
687 } 776 }
688 reader_ensure_data(reader, 1); 777 reader_ensure_data(reader, 1);
778 if (reader == mem_reader && mem_reader_quit) {
779 return EVENT_EOF;
780 }
689 uint8_t header = load_int8(&reader->buffer); 781 uint8_t header = load_int8(&reader->buffer);
690 uint8_t ret; 782 uint8_t ret;
691 uint32_t delta; 783 uint32_t delta;
692 uint8_t multi_start = 0; 784 uint8_t multi_start = 0;
693 if ((header & 0xF0) == (EVENT_MULTI << 4)) { 785 if ((header & 0xF0) == (EVENT_MULTI << 4)) {
733 reader->last_byte_address = load_int16(&reader->buffer); 825 reader->last_byte_address = load_int16(&reader->buffer);
734 } 826 }
735 return ret; 827 return ret;
736 } 828 }
737 829
830 #ifndef _WIN32
831 uint8_t mem_reader_next_event(event_out *out)
832 {
833 uint8_t ret = EVENT_EOF;
834 if (mem_reader->repeat_remaining) {
835 mem_reader->repeat_remaining--;
836 mem_reader->last_cycle += mem_reader->repeat_delta;
837 out->cycle = mem_reader->last_cycle;
838 ret = mem_reader->repeat_event;
839 }
840 if (ret < EVENT_PSG_REG) {
841 return ret;
842 }
843 pthread_mutex_lock(&event_log_lock);
844 if (ret == EVENT_EOF) {
845 ret = reader_next_event(mem_reader, &out->cycle);
846 }
847 switch (ret)
848 {
849 case EVENT_ADJUST:
850 out->address = load_int32(&mem_reader->buffer);
851 break;
852 case EVENT_VRAM_BYTE:
853 out->address = load_int16(&mem_reader->buffer);
854 break;
855 case EVENT_VRAM_BYTE_DELTA:
856 out->address = mem_reader->last_byte_address + load_int8(&mem_reader->buffer);
857 break;
858 case EVENT_VRAM_BYTE_ONE:
859 out->address = mem_reader->last_byte_address + 1;
860 break;
861 case EVENT_VRAM_BYTE_AUTO:
862 out->address = mem_reader->last_byte_address + out->autoinc;
863 break;
864 case EVENT_VRAM_WORD:
865 out->address = load_int8(&mem_reader->buffer) << 16;
866 out->address |= load_int16(&mem_reader->buffer);
867 break;
868 case EVENT_VRAM_WORD_DELTA:
869 out->address = mem_reader->last_word_address + load_int8(&mem_reader->buffer);
870 break;
871 case EVENT_VDP_REG:
872 case EVENT_VDP_INTRAM:
873 out->address = load_int8(&mem_reader->buffer);
874 break;
875 }
876 switch (ret)
877 {
878 case EVENT_VRAM_BYTE:
879 case EVENT_VRAM_BYTE_DELTA:
880 case EVENT_VRAM_BYTE_ONE:
881 case EVENT_VRAM_BYTE_AUTO:
882 mem_reader->last_byte_address = out->address;
883 case EVENT_VDP_REG:
884 out->value = load_int8(&mem_reader->buffer);
885 break;
886 case EVENT_VRAM_WORD:
887 case EVENT_VRAM_WORD_DELTA:
888 mem_reader->last_word_address = out->address;
889 case EVENT_VDP_INTRAM:
890 out->value = load_int16(&mem_reader->buffer);
891 break;
892 case EVENT_EOF:
893 free(mem_reader);
894 mem_reader = NULL;
895 break;
896 }
897 pthread_mutex_unlock(&event_log_lock);
898 return ret;
899 }
900 #endif
901
738 uint8_t reader_system_type(event_reader *reader) 902 uint8_t reader_system_type(event_reader *reader)
739 { 903 {
740 return load_int8(&reader->buffer); 904 return load_int8(&reader->buffer);
741 } 905 }
742 906