Skip to content

Commit 3ef1c0c

Browse files
committed
Add throttling to posix
1 parent 707e9ea commit 3ef1c0c

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed

Diff for: Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ cbin_load.o: cpu6.h cbin.h
3636

3737
math128.o: math128.h
3838

39-
mux.o : centurion.h mux.h
39+
mux.o : centurion.h mux.h console.h cpu6.h
4040

4141
clean:
4242
rm -f centurion *.o *~

Diff for: centurion.c

+5
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,9 @@ int main(int argc, char *argv[])
807807
}
808808
}
809809

810+
throttle_init();
811+
throttle_set_speed(1.0);
812+
810813
while (!emulator_done) {
811814
cpu6_execute_one(trace & TRACE_CPU);
812815
if (cpu6_halted())
@@ -846,6 +849,8 @@ int main(int argc, char *argv[])
846849
/* Update peripherals state */
847850
mux_poll(trace & TRACE_MUX);
848851

852+
throttle_emulation(cpu_timestamp_ns);
853+
849854
instruction_count++;
850855
if (terminate_at && instruction_count >= terminate_at) {
851856
printf("\nTerminated after %lli instructions\n", instruction_count);

Diff for: console.c

+43-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
#include <sys/select.h>
99
#include <sys/socket.h>
1010
#include <arpa/inet.h>
11+
#include <time.h>
1112

1213
#include "centurion.h"
1314
#include "console.h"
1415
#include "mux.h"
16+
#include "scheduler.h"
1517

1618
static struct termios saved_term, term;
1719

@@ -109,7 +111,7 @@ void mux_poll_fds(unsigned trace)
109111
int ifd = mux_get_in_poll_fd(unit);
110112

111113
if (ifd == -1)
112-
continue;
114+
continue;
113115
FD_SET(ifd, &i);
114116
if (ifd >= max_fd)
115117
max_fd = ifd + 1;
@@ -127,3 +129,43 @@ void mux_poll_fds(unsigned trace)
127129
mux_set_read_ready(unit, trace);
128130
}
129131
}
132+
133+
134+
// Get's the current time from the OS (in nanoseconds)
135+
uint64_t monotonic_time_ns() {
136+
struct timespec ts;
137+
clock_gettime(CLOCK_MONOTONIC, &ts);
138+
return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
139+
}
140+
141+
142+
static uint64_t throttle_start_time;
143+
static float throttle_speed;
144+
145+
void throttle_init() {
146+
throttle_start_time = monotonic_time_ns();
147+
}
148+
149+
void throttle_set_speed(float speed) {
150+
throttle_speed = speed;
151+
}
152+
153+
// Stall emulation if running faster than realtime
154+
void throttle_emulation(uint64_t expected_time_ns) {
155+
uint64_t now = monotonic_time_ns();
156+
uint64_t adjusted_target = expected_time_ns / throttle_speed;
157+
int64_t delta_ns = (throttle_start_time + adjusted_target) - now;
158+
159+
// We don't want to sleep if the delta is less than 5ms
160+
if (delta_ns > (5 * ONE_MILISECOND_NS)) {
161+
struct timespec delta;
162+
delta.tv_sec = delta_ns / 1000000000ULL;
163+
delta.tv_nsec = delta_ns % 1000000000ULL;
164+
165+
// sometimes nanosecond returns early, so loop until it finishs
166+
while (nanosleep(&delta, &delta));
167+
} else if (delta_ns < -(50 * ONE_MILISECOND_NS)) {
168+
// If have lagged by too much, we forgive the time
169+
//throttle_start_time += delta_ns;
170+
}
171+
}

Diff for: console.h

+8
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
15
void tty_init(void);
26
void net_init(unsigned short port);
7+
8+
void throttle_emulation(uint64_t expected_time_ns);
9+
void throttle_init();
10+
void throttle_set_speed(float speed);

Diff for: console_win32.c

+13
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,16 @@ void mux_poll_fds(unsigned trace)
103103
mux_set_read_ready(unit, trace);
104104
}
105105
}
106+
107+
108+
void throttle_emulation(uint64_t expected_time_ns) {
109+
// Unimplemented
110+
}
111+
112+
void throttle_init() {
113+
// Unimplemented
114+
}
115+
116+
void throttle_set_speed(float speed) {
117+
// Unimplemented
118+
}

0 commit comments

Comments
 (0)