making it work for aarch64 - seem to work on RPi

* changes to be fully tested!
* cas etc needs to be implemented for aarch64
sledge_graph
phani 5 years ago
parent bcc0aa2063
commit 7ff05b9d73

@ -4,13 +4,15 @@ RTDIR=src/
CFILES=${RTDIR}/*.c ${RTDIR}/libc/*.c ${RTDIR}/memory/common.c
RUNTIME=bin/awsmrt
INC=include/
ARCH := $(shell uname -m)
OPTFLAGS = -O3
OPTFLAGS += -flto -g
LDFLAGS = -Wl,--export-dynamic -ldl -lm
USE_MEM = USE_MEM_VM
CFLAGS = ${OPTFLAGS} -D${USE_MEM} -I${INC} -pthread
CFLAGS += -DX86_64
CFLAGS += -D${ARCH}
CFILES += ${RTDIR}/arch/${ARCH}/*.c
#CFLAGS += -DDEBUG
CFLAGS += -D_GNU_SOURCE
#CFLAGS += -DLOG_TO_FILE

@ -4,7 +4,8 @@
#include <unistd.h>
#include <ucontext.h>
#define ARCH_NREGS 31
#define ARCH_NREGS (2) // SP + PC only.
#define ARCH_SIG_JMP_OFF 0x100 // Based on code generated!
/**
* ARM64 code. Currently Unimplemented
@ -27,11 +28,86 @@ arch_context_init(arch_context_t *actx, reg_t ip, reg_t sp)
{
memset(&actx->mctx, 0, sizeof(mcontext_t));
memset((void *)actx->regs, 0, sizeof(reg_t) * ARCH_NREGS);
*(actx->regs) = sp;
*(actx->regs + 1) = ip;
}
static int
arch_mcontext_restore(mcontext_t *mc, arch_context_t *ctx)
{
assert(ctx != &worker_thread_base_context);
// if ctx->regs[0] is set, this was last in a user-level context switch state!
// else restore mcontext..
if (ctx->regs[0]) {
mc->sp = ctx->regs[0];
mc->pc = ctx->regs[1] + ARCH_SIG_JMP_OFF;
ctx->regs[0] = 0;
return 1;
} else {
memcpy(mc, &ctx->mctx, sizeof(mcontext_t));
memset(&ctx->mctx, 0, sizeof(mcontext_t));
}
return 0;
}
static void
arch_mcontext_save(arch_context_t *ctx, mcontext_t *mc)
{
assert(ctx != &worker_thread_base_context);
ctx->regs[0] = 0;
memcpy(&ctx->mctx, mc, sizeof(mcontext_t));
}
static inline int
arch_context_switch(arch_context_t *ca, arch_context_t *na)
{
if (!ca) {
assert(na);
// switching from "no sandbox to execute" state to "executing a sandbox"
ca = &worker_thread_base_context;
} else if (!na) {
assert(ca);
// switching from "executing a sandbox" to "no execution" state.
na = &worker_thread_base_context;
} else {
assert(na && ca);
// switching between sandboxes.
}
reg_t *cr = ca->regs, *nr = na->regs;
assert(cr && nr);
asm volatile ( "mov x0, sp\n\t"
"adr x1, reset%=\n\t"
"str x1, [%[curr], 8]\n\t"
"str x0, [%[curr]]\n\t"
"ldr x2, [%[next]]\n\t"
"cbz x2, slow%=\n\t"
"ldr x3, [%[next], 8]\n\t"
"mov sp, x2\n\t"
"br x3\n\t"
"slow%=:\n\t"
"br %[slowpath]\n\t"
".align 8\n\t"
"reset%=:\n\t"
"mov x1, #0\n\t"
"str x1, [%[next]]\n\t"
".align 8\n\t"
"exit%=:\n\t"
:
: [curr]"r"(cr), [next]"r"(nr), [slowpath]"r"(&worker_thread_sandbox_switch_preempt)
: "memory", "cc", "x0", "x1", "x2", "x3",
"x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26",
"d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15" );
return 0;
}

@ -1,9 +1,9 @@
#ifndef ARCH_CONTEXT_H
#define ARCH_CONTEXT_H
#if defined(AARCH64)
#if defined(AARCH64) || defined(aarch64)
#include "aarch64/context.h"
#elif defined(X86_64)
#elif defined(X86_64) || defined(x86_64)
#include "x86_64/context.h"
#else
#warning "Architecture not set. Using x86_64"

@ -71,4 +71,6 @@ worker_thread_get_libuv_handle(void)
return &worker_thread_uvio_handle;
}
unsigned long long __getcycles(void);
#endif /* SFRT_RUNTIME_H */

@ -1,20 +0,0 @@
#ifndef SFRT_UTIL_H
#define SFRT_UTIL_H
/**
* Get CPU time in cycles using the Intel instruction rdtsc
* @return CPU time in cycles
**/
static unsigned long long int
util__rdtsc(void)
{
unsigned long long int cpu_time_in_cycles = 0;
unsigned int cycles_lo;
unsigned int cycles_hi;
__asm__ volatile("rdtsc" : "=a"(cycles_lo), "=d"(cycles_hi));
cpu_time_in_cycles = (unsigned long long int)cycles_hi << 32 | cycles_lo;
return cpu_time_in_cycles;
}
#endif /* SFRT_UTIL_H */

@ -0,0 +1,19 @@
#if defined(AARCH64) || defined(aarch64)
#include <runtime.h>
unsigned long long int
__getcycles(void)
{
unsigned long long virtual_timer_value;
asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
return virtual_timer_value;
}
INLINE unsigned long long
env_getcycles(void)
{
return __getcycles();
}
#endif

@ -0,0 +1,175 @@
#if defined(X86_64) || defined(x86_64)
#include <runtime.h>
// Atomic functions, with definitions stolen from musl
i32
env_a_ctz_64(u64 x)
{
__asm__("bsf %1,%0" : "=r"(x) : "r"(x));
return x;
}
// static inline int a_ctz_l(unsigned long x)
//{
// __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
// return x;
//}
INLINE void
env_a_and_64(i32 p_off, u64 v)
{
uint64_t *p = worker_thread_get_memory_ptr_void(p_off, sizeof(uint64_t));
*p &= v;
// __asm__( "lock ; and %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
}
INLINE void
env_a_or_64(i32 p_off, i64 v)
{
assert(sizeof(i64) == sizeof(uint64_t));
uint64_t *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i64));
*p |= v;
// __asm__( "lock ; or %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
}
// static inline void a_or_l(volatile void *p, long v)
//{
// __asm__( "lock ; or %1, %0"
// : "=m"(*(long *)p) : "r"(v) : "memory" );
//}
//
// static inline void *a_cas_p(volatile void *p, void *t, void *s)
//{
// __asm__( "lock ; cmpxchg %3, %1"
// : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
// return t;
//}
//
i32
env_a_cas(i32 p_off, i32 t, i32 s)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i32));
__asm__("lock ; cmpxchg %3, %1" : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory");
return t;
}
void
env_a_or(i32 p_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i32));
__asm__("lock ; or %1, %0" : "=m"(*p) : "r"(v) : "memory");
}
// static inline void a_and(volatile int *p, int v)
//{
// __asm__( "lock ; and %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
//}
i32
env_a_swap(i32 x_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
i32
env_a_fetch_add(i32 x_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
void
env_a_inc(i32 x_off)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory");
}
void
env_a_dec(i32 x_off)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory");
}
void
env_a_store(i32 p_off, i32 x)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i32));
__asm__ __volatile__("mov %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory");
}
void
env_do_spin(i32 i)
{
__asm__ __volatile__("pause" : : : "memory");
}
void
env_do_crash(i32 i)
{
printf("crashing: %d\n", i);
assert(0);
}
int
env_a_ctz_32(i32 x)
{
__asm__("bsf %1,%0" : "=r"(x) : "r"(x));
return x;
}
void
env_do_barrier(i32 x)
{
__asm__ __volatile__("" : : : "memory");
}
unsigned long long int
__getcycles(void)
{
unsigned long long int cpu_time_in_cycles = 0;
unsigned int cycles_lo;
unsigned int cycles_hi;
__asm__ volatile("rdtsc" : "=a"(cycles_lo), "=d"(cycles_hi));
cpu_time_in_cycles = (unsigned long long int)cycles_hi << 32 | cycles_lo;
return cpu_time_in_cycles;
}
INLINE unsigned long long
env_getcycles(void)
{
return __getcycles();
}
#endif

@ -1,6 +1,5 @@
/* https://github.com/gwsystems/silverfish/blob/master/runtime/libc/libc_backing.c */
#include <runtime.h>
#include <util.h>
extern i32 inner_syscall_handler(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f);
@ -18,156 +17,6 @@ env___syscall(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f)
return env_syscall_handler(n, a, b, c, d, e, f);
}
// Atomic functions, with definitions stolen from musl
i32
env_a_ctz_64(u64 x)
{
__asm__("bsf %1,%0" : "=r"(x) : "r"(x));
return x;
}
// static inline int a_ctz_l(unsigned long x)
//{
// __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
// return x;
//}
INLINE void
env_a_and_64(i32 p_off, u64 v)
{
uint64_t *p = worker_thread_get_memory_ptr_void(p_off, sizeof(uint64_t));
*p &= v;
// __asm__( "lock ; and %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
}
INLINE void
env_a_or_64(i32 p_off, i64 v)
{
assert(sizeof(i64) == sizeof(uint64_t));
uint64_t *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i64));
*p |= v;
// __asm__( "lock ; or %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
}
// static inline void a_or_l(volatile void *p, long v)
//{
// __asm__( "lock ; or %1, %0"
// : "=m"(*(long *)p) : "r"(v) : "memory" );
//}
//
// static inline void *a_cas_p(volatile void *p, void *t, void *s)
//{
// __asm__( "lock ; cmpxchg %3, %1"
// : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
// return t;
//}
//
i32
env_a_cas(i32 p_off, i32 t, i32 s)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i32));
__asm__("lock ; cmpxchg %3, %1" : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory");
return t;
}
void
env_a_or(i32 p_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i32));
__asm__("lock ; or %1, %0" : "=m"(*p) : "r"(v) : "memory");
}
// static inline void a_and(volatile int *p, int v)
//{
// __asm__( "lock ; and %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
//}
i32
env_a_swap(i32 x_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
i32
env_a_fetch_add(i32 x_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
void
env_a_inc(i32 x_off)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory");
}
void
env_a_dec(i32 x_off)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *x = worker_thread_get_memory_ptr_void(x_off, sizeof(i32));
__asm__("lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory");
}
void
env_a_store(i32 p_off, i32 x)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int *p = worker_thread_get_memory_ptr_void(p_off, sizeof(i32));
__asm__ __volatile__("mov %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory");
}
void
env_do_spin(i32 i)
{
__asm__ __volatile__("pause" : : : "memory");
}
void
env_do_crash(i32 i)
{
printf("crashing: %d\n", i);
assert(0);
}
int
env_a_ctz_32(i32 x)
{
__asm__("bsf %1,%0" : "=r"(x) : "r"(x));
return x;
}
void
env_do_barrier(i32 x)
{
__asm__ __volatile__("" : : : "memory");
}
void
env___unmapself(u32 base, u32 size)
@ -189,8 +38,3 @@ env_cos(double d)
return cos(d);
}
INLINE unsigned long long
env_rdtsc(void)
{
return util__rdtsc();
}

@ -87,7 +87,7 @@ runtime_allocate_available_cores()
runtime_first_worker_processor = 0;
runtime_total_worker_processors = 1;
}
debuglog("Number of cores %u, sandboxing cores %u (start: %u) and module reqs %u\n",
printf("Number of cores %u, sandboxing cores %u (start: %u) and module reqs %u\n",
runtime_total_online_processors, runtime_total_worker_processors, runtime_first_worker_processor,
LISTENER_THREAD__CORE_ID);
}
@ -138,6 +138,7 @@ runtime_start_runtime_worker_threads()
assert(ret == 0);
}
debuglog("Sandboxing environment ready!\n");
printf("aWsm runtime ready!\n");
for (int i = 0; i < runtime_total_worker_processors; i++) {
int ret = pthread_join(runtime_worker_threads[i], NULL);
@ -159,7 +160,7 @@ main(int argc, char **argv)
runtime_process_debug_log_behavior();
#endif
printf("Starting Awsm\n");
printf("Initializing the runtime\n");
if (argc != 2) {
runtime_usage(argv[0]);
exit(-1);
@ -177,6 +178,8 @@ main(int argc, char **argv)
exit(-1);
}
printf("Starting listener thread\n");
listener_thread_initialize();
printf("Starting worker threads\n");
runtime_start_runtime_worker_threads();
}

@ -7,7 +7,6 @@
#include <module.h>
#include <module_database.h>
#include <runtime.h>
#include <util.h>
/***************************************
* Private Static Inline
@ -269,7 +268,6 @@ module_new_from_json(char *file_name)
is_active = (strcmp(val, "yes") == 0);
} else if (strcmp(key, "relative-deadline-us") == 0) {
relative_deadline_us = atoi(val);
printf("Set relative deadline to %d us\n", relative_deadline_us);
} else if (strcmp(key, "http-req-headers") == 0) {
assert(tokens[i + j + 1].type == JSMN_ARRAY);
assert(tokens[i + j + 1].size <= HTTP__MAX_HEADER_COUNT);
@ -329,4 +327,4 @@ module_new_from_json(char *file_name)
debuglog("Loaded %d module%s!\n", module_count, module_count > 1 ? "s" : "");
return 0;
}
}

@ -22,7 +22,6 @@
#include <sandbox_request.h>
#include <software_interrupt.h>
#include <types.h>
#include <util.h>
/***************************
* Shared Process State *
@ -84,7 +83,7 @@ listener_thread_main(void *dummy)
while (true) {
int request_count = epoll_wait(runtime_epoll_file_descriptor, epoll_events,
LISTENER_THREAD__MAX_EPOLL_EVENTS, -1);
u64 start_time = util__rdtsc();
u64 start_time = __getcycles();
for (int i = 0; i < request_count; i++) {
if (epoll_events[i].events & EPOLLERR) {
perror("epoll_wait");
@ -102,7 +101,6 @@ listener_thread_main(void *dummy)
assert(0);
}
total_requests++;
printf("Received Request %d at %lu\n", total_requests, start_time);
sandbox_request_t *sandbox_request =
sandbox_request__allocate(module, module->name, socket_descriptor,
@ -254,7 +252,8 @@ worker_thread_process_io(void)
/**
* TODO: What is this doing?
**/
void __attribute__((noinline)) __attribute__((noreturn)) worker_thread_sandbox_switch_preempt(void)
void __attribute__((noinline)) __attribute__((noreturn))
worker_thread_sandbox_switch_preempt(void)
{
pthread_kill(pthread_self(), SIGUSR1);
@ -468,4 +467,4 @@ worker_thread_exit_current_sandbox(void)
// unmap linear memory only!
munmap(current_sandbox->linear_memory_start, SBOX_MAX_MEM + PAGE_SIZE);
worker_thread_switch_to_sandbox(next_sandbox);
}
}

@ -6,7 +6,6 @@
#include <signal.h>
#include <uv.h>
#include <libuv_callbacks.h>
#include <util.h>
#include <current_sandbox.h>
/**
@ -140,8 +139,7 @@ current_sandbox_build_and_send_client_response(void)
done:
assert(sndsz == curr->request_response_data_length);
// Get End Timestamp
curr->total_time = util__rdtsc() - curr->start_time;
printf("Function returned in %lu cycles\n", curr->total_time);
curr->total_time = __getcycles() - curr->start_time;
#ifndef USE_HTTP_UVIO
int r = send(curr->client_socket_descriptor, curr->request_response_data, sndsz, 0);

@ -13,9 +13,9 @@ main(void)
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = util__rdtsc(), en = 0;
// unsigned long long st = getcycles(), en = 0;
// wrk();
// en = util__rdtsc();
// en = getcycles();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)

@ -11,9 +11,9 @@ main(void)
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = util__rdtsc(), en = 0;
// unsigned long long st = getcycles(), en = 0;
// wrk();
// en = util__rdtsc();
// en = getcycles();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)

@ -11,9 +11,9 @@ main(void)
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = util__rdtsc(), en = 0;
// unsigned long long st = getcycles(), en = 0;
// wrk();
// en = util__rdtsc();
// en = getcycles();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)

@ -11,9 +11,9 @@ main(void)
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = util__rdtsc(), en = 0;
// unsigned long long st = getcycles(), en = 0;
// wrk();
// en = util__rdtsc();
// en = getcycles();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)

@ -11,9 +11,9 @@ main(void)
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = util__rdtsc(), en = 0;
// unsigned long long st = getcycles(), en = 0;
// wrk();
// en = util__rdtsc();
// en = getcycles();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)

@ -1 +1 @@
Subproject commit 507ef4b2a14f45ccb246a202b485d175116e0b80
Subproject commit a44fe4566e1cca6fba95852e077311e5d3e21226
Loading…
Cancel
Save