Annotation of uae/src/timemgr.c, revision 1.1.1.2

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Supporting functions for timekeeping in event.h 
                      5:   *
                      6:   * Copyright 1995-2007 Bernd Schmidt
                      7:   */
                      8: 
                      9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
                     12: #include <ctype.h>
                     13: #include <assert.h>
                     14: 
                     15: #include "options.h"
                     16: #include "threaddep/thread.h"
                     17: #include "uae.h"
                     18: #include "gensound.h"
                     19: #include "sounddep/sound.h"
                     20: #include "events.h"
                     21: #include "memory.h"
                     22: #include "custom.h"
                     23: 
                     24: /* Events */
                     25: 
                     26: unsigned long int currcycle, nextevent;
                     27: struct ev eventtab[ev_max];
                     28: 
                     29: /* Time taken for one frame given the current display settings
                     30:    (NTSC vs. PAL).  */
                     31: frame_time_t vsynctime;
                     32: /* Timestamps of the next VSYNC event.  */
                     33: frame_time_t vsyncmintime;
                     34: 
                     35: int vsyncmintime_valid;
                     36: 
                     37: /* Set if gettimeofday has high enough resolution for our purposes.  */
                     38: int use_gtod = 0;
                     39: 
                     40: /* Adjusted in do_cycles to keep track of how many gettimeofday calls
                     41:    we can safely afford to skip.  */
                     42: unsigned long nr_gtod_to_skip = 50000;
                     43: /* An upper bound on the previous value, determined at runtime.  */
                     44: unsigned long max_gtod_to_skip = ULONG_MAX;
                     45: 
                     46: /* First time we measured in do_cycles when waiting for vsyncmintime.  */
                     47: frame_time_t first_measured_gtod;
                     48: /* Number of gettimeofday calls while waiting for vsyncmintime.
                     49:    Affected by nr_gtod_to_skip.  */
                     50: unsigned long nr_gtod_done;
                     51: /* A counter used internally by do_cycles to skip calls to gettimeofday.  */
                     52: unsigned long gtod_counter;
                     53: 
1.1.1.2 ! root       54: /* Set by the sound initialization code if the sound code can be used for
        !            55:    letting the m68k get extra cycles.  */
        !            56: int sync_with_sound;
        !            57: 
        !            58: /* The number of ticks in a frame_time_t per second.  */
        !            59: unsigned long syncbase;
1.1       root       60: 
                     61: int is_lastline;
1.1.1.2 ! root       62: volatile int delaying_for_sound;
        !            63: 
        !            64: unsigned long gtod_resolution, gtod_secs;
        !            65: 
        !            66: void init_gtod (void)
        !            67: {
        !            68:     struct timeval tv1, tv2;
        !            69:     gettimeofday (&tv1, NULL);
        !            70:     do {
        !            71:        gettimeofday (&tv2, NULL);
        !            72:     } while (tv1.tv_sec == tv2.tv_sec
        !            73:             && tv1.tv_usec == tv2.tv_usec);
        !            74: 
        !            75:     gtod_resolution = (tv2.tv_usec - tv1.tv_usec + 1000000 * (tv2.tv_sec - tv1.tv_sec));
        !            76:     if (gtod_resolution < 1000) {
        !            77:        use_gtod = 1;
        !            78:        syncbase = 1000000;
        !            79:     }
        !            80: }
1.1       root       81: 
                     82: void reset_frame_rate_hack (void)
                     83: {
                     84:     if (currprefs.m68k_speed != -1)
                     85:        return;
                     86: 
1.1.1.2 ! root       87:     if (! sync_with_sound && ! use_gtod) {
1.1       root       88:        currprefs.m68k_speed = 0;
                     89:        return;
                     90:     }
                     91: 
                     92:     vsyncmintime_valid = 0;
                     93:     is_lastline = 0;
                     94:     vsyncmintime = get_current_time(1);
                     95:     vsyncmintime += vsynctime;
                     96:     write_log ("Resetting frame rate hack\n");
                     97: }
                     98: 
                     99: void compute_vsynctime (void)
                    100: {
                    101:     vsynctime = syncbase / vblank_hz;
                    102:     if (use_gtod)
                    103:        vsynctime -= gtod_resolution < 100 ? 100 : gtod_resolution;
1.1.1.2 ! root      104:     if (currprefs.produce_sound > 1 && !sync_with_sound) {
1.1       root      105:        vsynctime = vsynctime * 19 / 20;
                    106:     }
                    107: }
                    108: 
                    109: void time_vsync (void)
                    110: {
1.1.1.2 ! root      111:     if (sync_with_sound) {
        !           112:        /* We don't strictly need it, but keep vsyncmintime accurate.  */
        !           113:        if (use_gtod) {
        !           114:            vsyncmintime = get_current_time(1) + vsynctime;
        !           115:            nr_gtod_done = 0;
        !           116:            vsyncmintime_valid = 1;
        !           117:        }
        !           118:        return;
        !           119:     }
        !           120: 
1.1       root      121:     if (vsyncmintime_valid) {
1.1.1.2 ! root      122:        if (nr_gtod_done > 50 && nr_gtod_to_skip < ULONG_MAX / 2) {
        !           123:            /* Try to reduce the number of gtod calls per frame - 50
        !           124:               should be enough, so whenever we exceed that number,
        !           125:               increase the number of gtod calls we skip - about 12%
        !           126:               each time.  */
        !           127:            nr_gtod_to_skip += nr_gtod_to_skip / 8;
1.1       root      128:        }
                    129:     }
                    130: 
                    131:     if (currprefs.m68k_speed == -1) {
                    132:        frame_time_t curr_time = get_current_time (1);
                    133:        /* If we got behind in one frame, try catching up by using the
                    134:           previous vsyncmintime as a base.  If we get too far behind,
                    135:           give up and reset.  */
                    136:        if (vsyncmintime_valid
                    137:            && curr_time > vsyncmintime
                    138:            && curr_time < vsyncmintime + vsynctime / 2)
                    139:            vsyncmintime += vsynctime;
                    140:        else
                    141:            vsyncmintime = curr_time + vsynctime;
                    142:        nr_gtod_done = 0;
                    143:        vsyncmintime_valid = 1;
                    144:     } else {
1.1.1.2 ! root      145:        /* No sound, and not using maximum CPU speed: delay until the frame
        !           146:           has taken 20ms.  */
        !           147:        if (currprefs.produce_sound < 2 && vsyncmintime_valid && use_gtod) {
1.1       root      148:            frame_time_t curr_time;
                    149:            do
                    150:                curr_time = get_current_time (0);
                    151:            while ((long int)(get_current_time (0) - vsyncmintime) < 0);
                    152:        }
                    153:        vsyncmintime = get_current_time (1) + vsynctime;
                    154:        vsyncmintime_valid = 1;
1.1.1.2 ! root      155:        nr_gtod_done = 0;
1.1       root      156:     }
                    157: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.