Skip to content

Instantly share code, notes, and snippets.

@larsbrinkhoff
Last active February 17, 2024 18:11
Show Gist options
  • Save larsbrinkhoff/a3df0c0c2e80bcfc48a2c75722c5094e to your computer and use it in GitHub Desktop.
Save larsbrinkhoff/a3df0c0c2e80bcfc48a2c75722c5094e to your computer and use it in GitHub Desktop.
Shared memory between PDP-10 and a remote computer
/* This is just pseudo code that happens to look a bit like C. */
/* The block of shared memory on the host looks like this. */
typedef struct {
/* Only written by PDP-10.*/
pid_t pdp10_pid;
word_t pdp10_data;
int pdp10_address;
/* Only written by remote side. */
pid_t remote_pid;
word_t remote_data;
int remote_nxm;
char remote_core[128*1024];
/* Written by both. */
mutex_t lock[128*1024];
word_t memory[128*1024];
} shared_memory_t;
void nxm(void)
{
/* Raise NXM for this memory access. */
}
void doorbell(int address)
{
pdp10_address = address;
/* Signal remote side with USR1, wait for USR2. */
kill(remote_pid, SIGUSR1);
sigtimedwait(SIGUSR2);
if(timeout) {
remote_pid = 0;
nxm();
}
if(remote_nxm)
nxm();
}
void gimme(int address)
{
/* Release lock on this core address. */
doorbell(GIMME | address);
if (pthread_mutex_timedlock(&lock[address], &timeout) == ETIMEDOUT) {
remote_pid = 0;
nxm();
}
}
word_t read_remote(int address)
{
word_t data;
if(remote_pid == 0)
nxm();
if(remote_core[address]) {
if (pthread_mutex_trylock(&lock[address], &timeout) == -1 && errno == EAGAIN)
gimme(address);
data = memory[address];
return data;
} else {
doorbell(READ | address);
return remote_data;
}
}
void write_remote(int address, word_t data)
{
if(remote_pid == 0)
nxm();
if(remote_core[address]) {
if (pthread_mutex_trylock(&lock[address], &timeout) == -1 && errno == EAGAIN)
gimme(GIMME | address);
memory[address] = data;
} else {
pdp10_data = data;
doorbell(WRITE | address);
}
}
void handle_usr1(int sig)
{
/* Remote side signaled PDP-10 with USR1, reply with USR2. */
pthread_mutex_unlock(&lock[remote_address]);
kill(remote_pid, SIGUSR2);
}
/* The remote handler looks like this. */
void handle_usr1(int sig)
{
if (pdp10_address & GIMME)
pthread_mutex_unlock(&lock[pdp10_address]);
else if (pdp10_address & READ)
pdp11_data = unibus_read(pdp10_address);
else if (pdp10_address & WRITE)
unibus_write(pdp10_address, pdp10_data);
kill(pdp10_pid, SIGUSR2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment