Mercurial > repos > blastem
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 |