Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 37ac6c4542b3
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 967145f2dc43
Choose a head ref
  • 5 commits
  • 21 files changed
  • 1 contributor

Commits on Apr 28, 2015

  1. Copy the full SHA
    283695e View commit details

Commits on Apr 29, 2015

  1. Copy the full SHA
    e5f7fcc View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    9ecbb4c View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    f60868f View commit details
  4. Copy the full SHA
    967145f View commit details
5 changes: 4 additions & 1 deletion artiq/coredevice/comm_tcp.py
Original file line number Diff line number Diff line change
@@ -30,7 +30,10 @@ def close(self):
def read(self, length):
r = bytes()
while len(r) < length:
r += self.socket.recv(min(8192, length - len(r)))
rn = self.socket.recv(min(8192, length - len(r)))
if not rn:
raise IOError("Connection closed")
r += rn
return r

def write(self, data):
2 changes: 2 additions & 0 deletions artiq/coredevice/runtime.py
Original file line number Diff line number Diff line change
@@ -12,6 +12,8 @@
llvm.initialize_all_asmprinters()

_syscalls = {
"watchdog_set": "i:i",
"watchdog_clear": "i:n",
"rtio_set_o": "Iii:n",
"rtio_set_oe": "Iib:n",
"rtio_set_sensitivity": "Iii:n",
10 changes: 4 additions & 6 deletions artiq/gateware/amp/mailbox.py
Original file line number Diff line number Diff line change
@@ -12,12 +12,10 @@ def __init__(self):
value = Signal(32)
for i in self.i1, self.i2:
self.sync += [
i.ack.eq(0),
If(i.cyc & i.stb & ~i.ack, i.ack.eq(1)),

i.dat_r.eq(value),
If(i.cyc & i.stb & i.we,
[If(i.sel[j], value[j*8:j*8+8].eq(i.dat_w[j*8:j*8+8]))
for j in range(4)]
i.ack.eq(0),
If(i.cyc & i.stb & ~i.ack,
i.ack.eq(1),
If(i.we, value.eq(i.dat_w))
)
]
37 changes: 27 additions & 10 deletions artiq/language/core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""
Core ARTIQ extensions to the Python language.
"""

from collections import namedtuple as _namedtuple
@@ -170,14 +169,12 @@ def set_syscall_manager(syscall_manager):

kernel_globals = ("sequential", "parallel",
"delay", "now", "at", "time_to_cycles", "cycles_to_time",
"syscall")
"syscall", "watchdog")


class _Sequential:
"""In a sequential block, statements are executed one after another, with
the time increasing as one moves down the statement list.
"""
the time increasing as one moves down the statement list."""
def __enter__(self):
_time_manager.enter_sequential()

@@ -243,7 +240,6 @@ def cycles_to_time(cycles, core=None):
:param time: Cycle count to convert.
:param core: Core device for which to perform the conversion. Specify only
when running in the interpreter (not in kernel).
"""
if core is None:
raise ValueError("Core device must be specified for time conversion")
@@ -257,19 +253,40 @@ def syscall(*args):
events, make RPCs, etc.
Only drivers should normally use ``syscall``.
"""
return _syscall_manager.do(*args)


class _DummyWatchdog:
def __init__(self, timeout):
pass

def __enter__(self):
pass

def __exit__(self, type, value, traceback):
pass


# Watchdogs are simply not enforced by default.
_watchdog_factory = _DummyWatchdog


def set_watchdog_factory(f):
global _watchdog_factory
_watchdog_factory = f


def watchdog(timeout):
return _watchdog_factory(timeout)


_encoded_exceptions = dict()


def EncodedException(eid):
"""Represents exceptions on the core device, which are identified
by a single number.
"""
by a single number."""
try:
return _encoded_exceptions[eid]
except KeyError:
5 changes: 4 additions & 1 deletion artiq/master/worker_impl.py
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
from artiq.master.worker_db import DBHub, ResultDB
from artiq.master.results import get_hdf5_output
from artiq.language.experiment import is_experiment
from artiq.language.core import set_watchdog_factory


def get_object():
@@ -66,13 +67,15 @@ def __exit__(self, type, value, traceback):
Watchdog._delete(self.wid)


set_watchdog_factory(Watchdog)


class Scheduler:
run_queued = make_parent_action("scheduler_run_queued", "run_params")
cancel_queued = make_parent_action("scheduler_cancel_queued", "rid")
run_timed = make_parent_action("scheduler_run_timed",
"run_params next_run")
cancel_timed = make_parent_action("scheduler_cancel_timed", "trid")
watchdog = Watchdog


def get_exp(file, exp):
6 changes: 3 additions & 3 deletions artiq/test/worker.py
Original file line number Diff line number Diff line change
@@ -10,19 +10,19 @@
class WatchdogNoTimeout(Experiment, AutoDB):
def run(self):
for i in range(10):
with self.scheduler.watchdog(0.5*s):
with watchdog(0.5*s):
sleep(0.1)


class WatchdogTimeout(Experiment, AutoDB):
def run(self):
with self.scheduler.watchdog(0.1*s):
with watchdog(0.1*s):
sleep(100.0)


class WatchdogTimeoutInBuild(Experiment, AutoDB):
def build(self):
with self.scheduler.watchdog(0.1*s):
with watchdog(0.1*s):
sleep(100.0)

def run(self):
2 changes: 1 addition & 1 deletion artiq/transforms/lower_units.py
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ def visit_Call(self, node):
else:
if any(hasattr(arg, "unit") for arg in node.args):
raise units.DimensionError
elif node.func.id in ("delay", "at", "time_to_cycles"):
elif node.func.id in ("delay", "at", "time_to_cycles", "watchdog"):
if getattr(node.args[0], "unit", None) != "s":
raise units.DimensionError
elif node.func.id == "check_unit":
49 changes: 47 additions & 2 deletions artiq/transforms/quantize_time.py
Original file line number Diff line number Diff line change
@@ -7,8 +7,7 @@
those calls.
The time_to_cycles and cycles_to_time core language functions are also
implemented here.
implemented here, as well as watchdog to syscall conversion.
"""

import ast
@@ -47,6 +46,7 @@ def _cycles_to_time(ref_period, node):
class _TimeQuantizer(ast.NodeTransformer):
def __init__(self, ref_period):
self.ref_period = ref_period
self.watchdog_id_counter = 0

def visit_Call(self, node):
funcname = node.func.id
@@ -78,6 +78,51 @@ def visit_Call(self, node):
self.generic_visit(node)
return node

def visit_With(self, node):
self.generic_visit(node)
if (isinstance(node.items[0].context_expr, ast.Call)
and node.items[0].context_expr.func.id == "watchdog"):

idname = "__watchdog_id_" + str(self.watchdog_id_counter)
self.watchdog_id_counter += 1

time = ast.BinOp(left=node.items[0].context_expr.args[0],
op=ast.Mult(),
right=ast.Num(1000))
time_int = ast.Call(
func=ast.Name("round", ast.Load()),
args=[time],
keywords=[], starargs=None, kwargs=None)
syscall_set = ast.Call(
func=ast.Name("syscall", ast.Load()),
args=[ast.Str("watchdog_set"), time_int],
keywords=[], starargs=None, kwargs=None)
stmt_set = ast.copy_location(
ast.Assign(targets=[ast.Name(idname, ast.Store())],
value=syscall_set),
node)

syscall_clear = ast.Call(
func=ast.Name("syscall", ast.Load()),
args=[ast.Str("watchdog_clear"),
ast.Name(idname, ast.Load())],
keywords=[], starargs=None, kwargs=None)
stmt_clear = ast.copy_location(ast.Expr(syscall_clear), node)

node.items[0] = ast.withitem(
context_expr=ast.Name(id="sequential",
ctx=ast.Load()),
optional_vars=None)
node.body = [
stmt_set,
ast.Try(body=node.body,
handlers=[],
orelse=[],
finalbody=[stmt_clear])
]
return node



def quantize_time(func_def, ref_period):
_TimeQuantizer(ref_period).visit(func_def)
2 changes: 1 addition & 1 deletion artiq/transforms/tools.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
embeddable_funcs = (
core_language.delay, core_language.at, core_language.now,
core_language.time_to_cycles, core_language.cycles_to_time,
core_language.syscall,
core_language.syscall, core_language.watchdog,
range, bool, int, float, round, len,
core_language.int64, core_language.round64,
Fraction, units.Quantity, units.check_unit, core_language.EncodedException
2 changes: 1 addition & 1 deletion soc/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include $(MSCDIR)/software/common.mak

OBJECTS := isr.o flash_storage.o elf_loader.o services.o session.o log.o test_mode.o kloader.o mailbox.o ksupport_data.o main.o
OBJECTS := isr.o flash_storage.o clock.o elf_loader.o services.o session.o log.o test_mode.o kloader.o mailbox.o ksupport_data.o main.o
OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o dds.o

CFLAGS += -Ilwip/src/include -Iliblwip
81 changes: 81 additions & 0 deletions soc/runtime/clock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <generated/csr.h>

#include "log.h"
#include "clock.h"

static int clkdiv;

void clock_init(void)
{
timer0_en_write(0);
timer0_load_write(0x7fffffffffffffffLL);
timer0_reload_write(0x7fffffffffffffffLL);
timer0_en_write(1);
clkdiv = identifier_frequency_read()/1000;
}

long long int clock_get_ms(void)
{
long long int clock_sys;
long long int clock_ms;

timer0_update_value_write(1);
clock_sys = 0x7fffffffffffffffLL - timer0_value_read();

clock_ms = clock_sys/clkdiv;
return clock_ms;
}

struct watchdog {
int active;
long long int threshold;
};

static struct watchdog watchdogs[MAX_WATCHDOGS];

void watchdog_init(void)
{
int i;

for(i=0;i<MAX_WATCHDOGS;i++)
watchdogs[i].active = 0;
}

int watchdog_set(int ms)
{
int i, id;

id = -1;
for(i=0;i<MAX_WATCHDOGS;i++)
if(!watchdogs[i].active) {
id = i;
break;
}
if(id < 0) {
log("Failed to add watchdog");
return id;
}

watchdogs[id].active = 1;
watchdogs[id].threshold = clock_get_ms() + ms;
return id;
}

void watchdog_clear(int id)
{
if((id < 0) || (id >= MAX_WATCHDOGS))
return;
watchdogs[id].active = 0;
}

int watchdog_expired(void)
{
int i;
long long int t;

t = 0x7fffffffffffffffLL;
for(i=0;i<MAX_WATCHDOGS;i++)
if(watchdogs[i].active && (watchdogs[i].threshold < t))
t = watchdogs[i].threshold;
return clock_get_ms() > t;
}
14 changes: 14 additions & 0 deletions soc/runtime/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef __CLOCK_H
#define __CLOCK_H

void clock_init(void);
long long int clock_get_ms(void);

#define MAX_WATCHDOGS 16

void watchdog_init(void);
int watchdog_set(int ms);
void watchdog_clear(int id);
int watchdog_expired(void);

#endif /* __CLOCK_H */
2 changes: 2 additions & 0 deletions soc/runtime/gen_service_table.py
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
services = [
("syscalls", [
("rpc", "rpc"),
("watchdog_set", "watchdog_set"),
("watchdog_clear", "watchdog_clear"),
("rtio_set_o", "rtio_set_o"),
("rtio_set_oe", "rtio_set_oe"),
("rtio_set_sensitivity", "rtio_set_sensitivity"),
1 change: 1 addition & 0 deletions soc/runtime/kloader.c
Original file line number Diff line number Diff line change
@@ -102,4 +102,5 @@ void kloader_start_idle_kernel(void)
void kloader_stop_kernel(void)
{
kernel_cpu_reset_write(1);
mailbox_acknowledge();
}
Loading