chore: add clang-format from Composite (#5)

* chore: add clang-format from Composite

* chore: cleanup JSON

* chore: add clang-format from Composite

* chore: stylistic corrections

* chore: ignore swap files and vscode conf

* chore: check semver of clang-format and require 9
sledge_graph
Sean McBride 5 years ago committed by GitHub
parent b37b570344
commit e61be257f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,70 @@
---
BasedOnStyle: Mozilla
IndentWidth: 8
Language: Cpp
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignConsecutiveMacros: true
AlignEscapedNewlines: Left
AlignTrailingComments: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: AllDefinitions
BinPackArguments: true
BinPackParameters: true
BraceWrapping: {
AfterClass: false,
AfterControlStatement: false,
AfterEnum: true,
AfterFunction: true,
AfterNamespace: false,
AfterStruct: false,
AfterUnion: false,
BeforeElse: false,
IndentBraces: false,
}
BreakBeforeBraces: Custom
BreakBeforeBinaryOperators: NonAssignment
ColumnLimit: 120
Cpp11BracedListStyle: false
IndentCaseLabels: false
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 2
DerivePointerAlignment: false
PointerAlignment: Right
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 8
UseTab: ForIndentation
PenaltyBreakAssignment: 100
PenaltyBreakBeforeFirstCallParameter: 1000
PenaltyReturnTypeOnItsOwnLine: 0

6
.gitignore vendored

@ -54,3 +54,9 @@ dkms.conf
runtime/tags
runtime/bin
runtime/tests/tmp/
# Swap Files
*.swp
# Editor Configs
.vscode

@ -0,0 +1,30 @@
#!/bin/bash
utility="clang-format"
utility_version="$("$utility" --version 2>/dev/null)" || {
echo "$utility not found in path!"
exit 1
}
regex="version ([0-9]+).([0-9]+).([0-9]+)"
declare -i major=0
declare -i minor=0
declare -i patch=0
declare -i required_major=9
declare -i required_minor=0
declare -i required_patch=0
if [[ "$utility_version" =~ $regex ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
patch="${BASH_REMATCH[3]}"
fi
if ((major < required_major)) || ((minor < required_minor)) || ((patch < required_patch)); then
echo "$utility $required_major.$required_minor.$required_patch required, but is $major.$minor.$patch"
exit 1
fi
find ./runtime -type f -path "./*.[ch]" | # Match all *.c and *.h files in ./runtime
grep --invert-match -E "./runtime/jsmn/*|./runtime/http-parser/*" | # Excluding those in the jsmn or http-parser submodules
xargs clang-format -i # And format them with clang-format

@ -10,102 +10,102 @@
INLINE u32
rotl_u32(u32 n, u32 c_u32)
{
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u32 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u32 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
c &= mask;
return (n << c) | (n >> ((-c) & mask));
c &= mask;
return (n << c) | (n >> ((-c) & mask));
}
INLINE u32
rotr_u32(u32 n, u32 c_u32)
{
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u32 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u32 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
c &= mask;
return (n>>c) | (n << ((-c) & mask));
c &= mask;
return (n >> c) | (n << ((-c) & mask));
}
INLINE u64
rotl_u64(u64 n, u64 c_u64)
{
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u64 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u64 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
c &= mask;
return (n << c) | (n >> ((-c) & mask));
c &= mask;
return (n << c) | (n >> ((-c) & mask));
}
INLINE u64
rotr_u64(u64 n, u64 c_u64)
{
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u64 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
// WASM requires a modulus here (usually a single bitwise op, but it means we need no assert)
unsigned int c = c_u64 % (CHAR_BIT * sizeof(n));
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
c &= mask;
return (n >> c) | (n << ((-c) & mask));
c &= mask;
return (n >> c) | (n << ((-c) & mask));
}
// Now safe division and remainder
INLINE u32
u32_div(u32 a, u32 b)
{
assert(b);
return a / b;
assert(b);
return a / b;
}
INLINE u32
u32_rem(u32 a, u32 b)
{
assert(b);
return a % b;
assert(b);
return a % b;
}
INLINE i32
i32_div(i32 a, i32 b)
{
assert(b && (a != INT32_MIN || b != -1));
return a / b;
assert(b && (a != INT32_MIN || b != -1));
return a / b;
}
INLINE i32
i32_rem(i32 a, i32 b)
{
assert(b && (a != INT32_MIN || b != -1));
return a % b;
assert(b && (a != INT32_MIN || b != -1));
return a % b;
}
INLINE u64
u64_div(u64 a, u64 b)
{
assert(b);
return a / b;
assert(b);
return a / b;
}
INLINE u64
u64_rem(u64 a, u64 b)
{
assert(b);
return a % b;
assert(b);
return a % b;
}
INLINE i64
i64_div(i64 a, i64 b)
{
assert(b && (a != INT64_MIN || b != -1));
return a / b;
assert(b && (a != INT64_MIN || b != -1));
return a / b;
}
INLINE i64
i64_rem(i64 a, i64 b)
{
assert(b && (a != INT64_MIN || b != -1));
return a % b;
assert(b && (a != INT64_MIN || b != -1));
return a % b;
}
// float to integer conversion methods
@ -114,76 +114,76 @@ i64_rem(i64 a, i64 b)
u32
u32_trunc_f32(float f)
{
assert(0 <= f && f <= UINT32_MAX);
return (u32) f;
assert(0 <= f && f <= UINT32_MAX);
return (u32)f;
}
i32
i32_trunc_f32(float f)
{
assert(INT32_MIN <= f && f <= INT32_MAX );
return (i32) f;
assert(INT32_MIN <= f && f <= INT32_MAX);
return (i32)f;
}
u32
u32_trunc_f64(double f)
{
assert(0 <= f && f <= UINT32_MAX);
return (u32) f;
assert(0 <= f && f <= UINT32_MAX);
return (u32)f;
}
i32
i32_trunc_f64(double f)
{
assert(INT32_MIN <= f && f <= INT32_MAX );
return (i32) f;
assert(INT32_MIN <= f && f <= INT32_MAX);
return (i32)f;
}
u64
u64_trunc_f32(float f)
{
assert(0 <= f && f <= UINT64_MAX);
return (u64) f;
assert(0 <= f && f <= UINT64_MAX);
return (u64)f;
}
i64
i64_trunc_f32(float f)
{
assert(INT64_MIN <= f && f <= INT64_MAX);
return (i64) f;
assert(INT64_MIN <= f && f <= INT64_MAX);
return (i64)f;
}
u64
u64_trunc_f64(double f)
{
assert(0 <= f && f <= UINT64_MAX);
return (u64) f;
assert(0 <= f && f <= UINT64_MAX);
return (u64)f;
}
i64
i64_trunc_f64(double f)
{
assert(INT64_MIN <= f && f <= INT64_MAX);
return (i64) f;
assert(INT64_MIN <= f && f <= INT64_MAX);
return (i64)f;
}
// Float => Float truncation functions
INLINE float
f32_trunc_f32(float f)
{
return trunc(f);
return trunc(f);
}
INLINE float
f32_min(float a, float b)
{
return a < b ? a : b;
return a < b ? a : b;
}
INLINE float
f32_max(float a, float b)
{
return a > b ? a : b;
return a > b ? a : b;
}
INLINE float
@ -195,13 +195,13 @@ f32_floor(float a)
INLINE double
f64_min(double a, double b)
{
return a < b ? a : b;
return a < b ? a : b;
}
INLINE double
f64_max(double a, double b)
{
return a > b ? a : b;
return a > b ? a : b;
}
INLINE double
@ -209,5 +209,3 @@ f64_floor(double a)
{
return floor(a);
}

@ -8,7 +8,7 @@ INLINE float
get_f32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(float *)address;
}
@ -17,7 +17,7 @@ INLINE double
get_f64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(double *)address;
}
@ -26,7 +26,7 @@ INLINE i8
get_i8(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(i8 *)address;
}
@ -35,7 +35,7 @@ INLINE i16
get_i16(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(i16 *)address;
}
@ -44,7 +44,7 @@ INLINE i32
get_i32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(i32 *)address;
}
@ -53,7 +53,7 @@ INLINE i64
get_i64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(i64 *)address;
}
@ -62,7 +62,7 @@ INLINE i32
get_global_i32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(i32 *)address;
}
@ -71,7 +71,7 @@ INLINE i64
get_global_i64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
return *(i64 *)address;
}
@ -81,7 +81,7 @@ INLINE void
set_f32(i32 offset, float v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(float *)address = v;
}
@ -90,7 +90,7 @@ INLINE void
set_f64(i32 offset, double v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(double *)address = v;
}
@ -99,7 +99,7 @@ INLINE void
set_i8(i32 offset, i8 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(i8 *)address = v;
}
@ -108,7 +108,7 @@ INLINE void
set_i16(i32 offset, i16 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(i16 *)address = v;
}
@ -117,7 +117,7 @@ INLINE void
set_i32(i32 offset, i32 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(i32 *)address = v;
}
@ -126,7 +126,7 @@ INLINE void
set_i64(i32 offset, i64 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(i64 *)address = v;
}
@ -135,7 +135,7 @@ INLINE void
set_global_i32(i32 offset, i32 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(i32 *)address = v;
}
@ -144,7 +144,7 @@ INLINE void
set_global_i64(i32 offset, i64 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
void *address = &mem_as_chars[offset];
*(i64 *)address = v;
}
@ -157,7 +157,7 @@ get_function_from_table(u32 idx, u32 type_id)
struct indirect_table_entry f = module_indirect_table[idx];
// assert(f.type_id == type_id);
// assert(f.type_id == type_id);
assert(f.func_pointer);
return f.func_pointer;

@ -14,18 +14,18 @@ typedef uint64_t reg_t;
extern void __attribute__((noreturn)) sandbox_switch_preempt(void);
struct arch_context {
reg_t regs[ARCH_NREGS];
reg_t regs[ARCH_NREGS];
mcontext_t mctx;
};
typedef struct arch_context arch_context_t;
typedef struct arch_context arch_context_t;
extern __thread arch_context_t base_context;
static inline void
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);
memset((void *)actx->regs, 0, sizeof(reg_t) * ARCH_NREGS);
}
static inline int

@ -27,7 +27,7 @@
*/
typedef uint64_t reg_t;
#define ARCH_NREGS (16 /* GP registers */ + 1 /* for IP */)
#define ARCH_NREGS (16 /* GP registers */ + 1 /* for IP */)
#define ARCH_SIG_JMP_OFF 8
/*
@ -37,11 +37,11 @@ typedef uint64_t reg_t;
extern void __attribute__((noreturn)) sandbox_switch_preempt(void);
struct arch_context {
reg_t regs[ARCH_NREGS];
reg_t regs[ARCH_NREGS];
mcontext_t mctx;
};
typedef struct arch_context arch_context_t;
typedef struct arch_context arch_context_t;
extern __thread arch_context_t base_context;
static void
@ -63,7 +63,7 @@ arch_mcontext_restore(mcontext_t *mc, arch_context_t *ctx)
if (ctx->regs[5]) {
mc->gregs[REG_RSP] = ctx->regs[5];
mc->gregs[REG_RIP] = ctx->regs[16] + ARCH_SIG_JMP_OFF;
ctx->regs[5] = 0;
ctx->regs[5] = 0;
return 1;
} else {
@ -74,34 +74,30 @@ arch_mcontext_restore(mcontext_t *mc, arch_context_t *ctx)
return 0;
}
static void __attribute__((noinline))
arch_context_init(arch_context_t *actx, reg_t ip, reg_t sp)
static void __attribute__((noinline)) 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);
if (sp) {
/*
/*
* context_switch conventions: bp is expected to be on top of the stack
* when co-op context switching..
* when co-op context switching..
*
* so push sp on this new stack and use
* so push sp on this new stack and use
* that new sp as sp for switching to sandbox!
*/
asm volatile (
"movq %%rsp, %%rbx\n\t" \
"movq %%rax, %%rsp\n\t" \
"pushq %%rax\n\t" \
"movq %%rsp, %%rax\n\t" \
"movq %%rbx, %%rsp\n\t" \
: "=a" (sp)
: "a" (sp)
: "memory", "cc", "rbx"
);
asm volatile("movq %%rsp, %%rbx\n\t"
"movq %%rax, %%rsp\n\t"
"pushq %%rax\n\t"
"movq %%rsp, %%rax\n\t"
"movq %%rbx, %%rsp\n\t"
: "=a"(sp)
: "a"(sp)
: "memory", "cc", "rbx");
}
*(actx->regs + 5) = sp;
*(actx->regs + 5) = sp;
*(actx->regs + 16) = ip;
}
@ -128,30 +124,27 @@ arch_context_switch(arch_context_t *ca, arch_context_t *na)
/* TODO: slowpath: signal the current pthread if resuming a preempted sandbox! */
asm volatile ( \
"pushq %%rbp\n\t" \
"movq %%rsp, %%rbp\n\t" \
"movq $2f, 128(%%rax)\n\t" \
"movq %%rsp, 40(%%rax)\n\t" \
"cmpq $0, 40(%%rbx)\n\t" \
"je 1f\n\t" \
"movq 40(%%rbx), %%rsp\n\t" \
"jmpq *128(%%rbx)\n\t" \
"1:\n\t" \
"call sandbox_switch_preempt\n\t" \
".align 8\n\t" \
"2:\n\t" \
"movq $0, 40(%%rbx)\n\t" \
".align 8\n\t" \
"3:\n\t" \
"popq %%rbp\n\t" \
:
: "a" (cr), "b" (nr)
: "memory", "cc", "rcx", "rdx", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10","xmm11","xmm12","xmm13","xmm14","xmm15"
);
asm volatile("pushq %%rbp\n\t"
"movq %%rsp, %%rbp\n\t"
"movq $2f, 128(%%rax)\n\t"
"movq %%rsp, 40(%%rax)\n\t"
"cmpq $0, 40(%%rbx)\n\t"
"je 1f\n\t"
"movq 40(%%rbx), %%rsp\n\t"
"jmpq *128(%%rbx)\n\t"
"1:\n\t"
"call sandbox_switch_preempt\n\t"
".align 8\n\t"
"2:\n\t"
"movq $0, 40(%%rbx)\n\t"
".align 8\n\t"
"3:\n\t"
"popq %%rbp\n\t"
:
: "a"(cr), "b"(nr)
: "memory", "cc", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
"xmm12", "xmm13", "xmm14", "xmm15");
return 0;
}

@ -19,95 +19,94 @@
* PPoPP implementation paper, "Correct and Efficient Work-Stealing for Weak Memory Models"
* https://www.di.ens.fr/~zappa/readings/ppopp13.pdf
*/
//TODO: dynamic resize!
#define DEQUE_MAX_SZ (1<<23)
// TODO: dynamic resize!
#define DEQUE_MAX_SZ (1 << 23)
#define DEQUE_PROTOTYPE(name, type) \
struct deque_##name { \
type wrk[DEQUE_MAX_SZ]; \
long size; \
\
volatile long top; \
volatile long bottom; \
}; \
\
static inline void \
deque_init_##name(struct deque_##name *q, size_t sz) \
{ \
memset(q, 0, sizeof(struct deque_##name)); \
\
if (sz) { \
/* only for size with pow of 2 */ \
/* assert((sz & (sz - 1)) == 0); */ \
assert(sz <= DEQUE_MAX_SZ); \
} else { \
sz = DEQUE_MAX_SZ; \
} \
\
q->size = sz; \
} \
\
/* Use mutual exclusion locks around push/pop if multi-threaded. */ \
static inline int \
deque_push_##name(struct deque_##name *q, type *w) \
{ \
long ct, cb; \
\
ct = q->top; \
cb = q->bottom; \
\
/* nope, fixed size only */ \
if (q->size - 1 < (cb - ct)) return -ENOSPC; \
\
q->wrk[cb] = *w; \
__sync_synchronize(); \
if (__sync_bool_compare_and_swap(&q->bottom, cb, cb + 1) == false) assert(0); \
\
return 0; \
} \
\
/* Use mutual exclusion locks around push/pop if multi-threaded. */ \
static inline int \
deque_pop_##name(struct deque_##name *q, type *w) \
{ \
long ct = 0, sz = 0; \
long cb = q->bottom - 1; \
int ret = 0; \
\
if (__sync_bool_compare_and_swap(&q->bottom, cb + 1, cb) == false) assert(0); \
\
ct = q->top; \
sz = cb - ct; \
if (sz < 0) { \
if (__sync_bool_compare_and_swap(&q->bottom, cb, ct) == false) assert(0); \
\
return -ENOENT; \
} \
\
*w = q->wrk[cb]; \
if (sz > 0) return 0; \
\
ret = __sync_bool_compare_and_swap(&q->top, ct, ct + 1); \
if (__sync_bool_compare_and_swap(&q->bottom, cb, ct + 1) == false) assert(0); \
if (ret == false) { *w = NULL; return -ENOENT; } \
\
return 0; \
} \
\
static inline int \
deque_steal_##name(struct deque_##name *q, type *w) \
{ \
long ct, cb; \
\
ct = q->top; \
cb = q->bottom; \
\
if (ct >= cb) return -ENOENT; \
\
*w = q->wrk[ct]; \
if (__sync_bool_compare_and_swap(&q->top, ct, ct + 1) == false) return -EAGAIN; \
\
return 0; \
}
#define DEQUE_PROTOTYPE(name, type) \
struct deque_##name { \
type wrk[DEQUE_MAX_SZ]; \
long size; \
\
volatile long top; \
volatile long bottom; \
}; \
\
static inline void deque_init_##name(struct deque_##name *q, size_t sz) \
{ \
memset(q, 0, sizeof(struct deque_##name)); \
\
if (sz) { \
/* only for size with pow of 2 */ \
/* assert((sz & (sz - 1)) == 0); */ \
assert(sz <= DEQUE_MAX_SZ); \
} else { \
sz = DEQUE_MAX_SZ; \
} \
\
q->size = sz; \
} \
\
/* Use mutual exclusion locks around push/pop if multi-threaded. */ \
static inline int deque_push_##name(struct deque_##name *q, type *w) \
{ \
long ct, cb; \
\
ct = q->top; \
cb = q->bottom; \
\
/* nope, fixed size only */ \
if (q->size - 1 < (cb - ct)) return -ENOSPC; \
\
q->wrk[cb] = *w; \
__sync_synchronize(); \
if (__sync_bool_compare_and_swap(&q->bottom, cb, cb + 1) == false) assert(0); \
\
return 0; \
} \
\
/* Use mutual exclusion locks around push/pop if multi-threaded. */ \
static inline int deque_pop_##name(struct deque_##name *q, type *w) \
{ \
long ct = 0, sz = 0; \
long cb = q->bottom - 1; \
int ret = 0; \
\
if (__sync_bool_compare_and_swap(&q->bottom, cb + 1, cb) == false) assert(0); \
\
ct = q->top; \
sz = cb - ct; \
if (sz < 0) { \
if (__sync_bool_compare_and_swap(&q->bottom, cb, ct) == false) assert(0); \
\
return -ENOENT; \
} \
\
*w = q->wrk[cb]; \
if (sz > 0) return 0; \
\
ret = __sync_bool_compare_and_swap(&q->top, ct, ct + 1); \
if (__sync_bool_compare_and_swap(&q->bottom, cb, ct + 1) == false) assert(0); \
if (ret == false) { \
*w = NULL; \
return -ENOENT; \
} \
\
return 0; \
} \
\
static inline int deque_steal_##name(struct deque_##name *q, type *w) \
{ \
long ct, cb; \
\
ct = q->top; \
cb = q->bottom; \
\
if (ct >= cb) return -ENOENT; \
\
*w = q->wrk[ct]; \
if (__sync_bool_compare_and_swap(&q->top, ct, ct + 1) == false) return -EAGAIN; \
\
return 0; \
}
#endif /* DEQUE_H */

@ -14,14 +14,14 @@ struct http_header {
struct http_resp_header {
char *hdr;
int len;
int len;
};
struct http_request {
struct http_header headers[HTTP_HEADERS_MAX];
int nheaders;
char *body;
int bodylen, bodyrlen;
int nheaders;
char * body;
int bodylen, bodyrlen;
// additional for http-parser
int last_was_value;
int header_end;
@ -30,13 +30,13 @@ struct http_request {
struct http_response {
struct http_resp_header headers[HTTP_HEADERS_MAX];
int nheaders;
char *body;
int bodylen;
char *status;
int stlen;
int nheaders;
char * body;
int bodylen;
char * status;
int stlen;
#ifdef USE_HTTP_UVIO
uv_buf_t bufs[HTTP_HEADERS_MAX * 2 + 3]; //max headers, one line for status code, remaining for body!
uv_buf_t bufs[HTTP_HEADERS_MAX * 2 + 3]; // max headers, one line for status code, remaining for body!
#else
struct iovec bufs[HTTP_HEADERS_MAX * 2 + 3];
#endif

@ -8,44 +8,45 @@ struct module {
char name[MOD_NAME_MAX];
char path[MOD_PATH_MAX];
void *dl_handle;
void * dl_handle;
mod_main_fn_t entry_fn;
mod_glb_fn_t glb_init_fn;
mod_mem_fn_t mem_init_fn;
mod_tbl_fn_t tbl_init_fn;
mod_glb_fn_t glb_init_fn;
mod_mem_fn_t mem_init_fn;
mod_tbl_fn_t tbl_init_fn;
mod_libc_fn_t libc_init_fn;
struct indirect_table_entry indirect_table[INDIRECT_TABLE_SIZE];
i32 nargs;
u32 stack_size; // a specification?
u64 max_memory; //perhaps a specification of the module. (max 4GB)
u32 timeout; //again part of the module specification.
u64 max_memory; // perhaps a specification of the module. (max 4GB)
u32 timeout; // again part of the module specification.
u32 refcnt; //ref count how many instances exist here.
u32 refcnt; // ref count how many instances exist here.
// stand-alone vs serverless
#ifndef STANDALONE
struct sockaddr_in srvaddr;
int srvsock, srvport;
int srvsock, srvport;
// unfortunately, using UV for accepting connections is not great!
// on_connection, to create a new accepted connection, will have to
// init a tcp handle, which requires a uvloop. cannot use main as
// init a tcp handle, which requires a uvloop. cannot use main as
// rest of the connection is handled in sandboxing threads, with per-core(per-thread) tls data-structures.
// so, using direct epoll for accepting connections.
// uv_handle_t srvuv;
// uv_handle_t srvuv;
unsigned long max_req_sz, max_resp_sz, max_rr_sz; // req/resp from http, (resp size including headers!)..
int nreqhdrs, nresphdrs;
char reqhdrs[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ];
char rqctype[HTTP_HEADERVAL_MAXSZ];
char rspctype[HTTP_HEADERVAL_MAXSZ];
char resphdrs[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ];
int nreqhdrs, nresphdrs;
char reqhdrs[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ];
char rqctype[HTTP_HEADERVAL_MAXSZ];
char rspctype[HTTP_HEADERVAL_MAXSZ];
char resphdrs[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ];
#endif
};
struct module *module_alloc(char *mod_name, char *mod_path, i32 nargs, u32 stack_sz, u32 max_heap, u32 timeout, int port, int req_sz, int resp_sz);
struct module *module_alloc(char *mod_name, char *mod_path, i32 nargs, u32 stack_sz, u32 max_heap, u32 timeout,
int port, int req_sz, int resp_sz);
// frees only if refcnt == 0
void module_free(struct module *mod);
void module_free(struct module *mod);
struct module *module_find_by_name(char *name);
struct module *module_find_by_sock(int sock);
@ -54,7 +55,7 @@ module_http_info(struct module *m, int nrq, char *rqs, char rqtype[], int nrs, c
{
#ifndef STANDALONE
assert(m);
m->nreqhdrs = nrq;
m->nreqhdrs = nrq;
m->nresphdrs = nrs;
memcpy(m->reqhdrs, rqs, HTTP_HEADER_MAXSZ * HTTP_HEADERS_MAX);
memcpy(m->resphdrs, rs, HTTP_HEADER_MAXSZ * HTTP_HEADERS_MAX);

@ -66,19 +66,27 @@ struct ps_list_head {
static inline void
ps_list_ll_init(struct ps_list *l)
{ l->n = l->p = l; }
{
l->n = l->p = l;
}
static inline void
ps_list_head_init(struct ps_list_head *lh)
{ ps_list_ll_init(&lh->l); }
{
ps_list_ll_init(&lh->l);
}
static inline int
ps_list_ll_empty(struct ps_list *l)
{ return l->n == l; }
{
return l->n == l;
}
static inline int
ps_list_head_empty(struct ps_list_head *lh)
{ return ps_list_ll_empty(&lh->l); }
{
return ps_list_ll_empty(&lh->l);
}
static inline void
ps_list_ll_add(struct ps_list *l, struct ps_list *new)
@ -100,8 +108,7 @@ ps_list_ll_rem(struct ps_list *l)
#define ps_offsetof(s, field) __builtin_offsetof(s, field)
//#define ps_offsetof(s, field) ((unsigned long)&(((s *)0)->field))
#define ps_container(intern, type, field) \
((type *)((char *)(intern) - ps_offsetof(type, field)))
#define ps_container(intern, type, field) ((type *)((char *)(intern)-ps_offsetof(type, field)))
/*
* Get a pointer to the object containing *l, of a type shared with
@ -110,8 +117,7 @@ ps_list_ll_rem(struct ps_list *l)
* a list. Do _not_ use this function. It is a utility used by the
* following functions.
*/
#define ps_list_obj_get(l, o, lname) \
ps_container(l, __typeof__(*(o)), lname)
#define ps_list_obj_get(l, o, lname) ps_container(l, __typeof__(*(o)), lname)
//(typeof (*(o)) *)(((char*)(l)) - ps_offsetof(typeof(*(o)), lname))
@ -120,17 +126,17 @@ ps_list_ll_rem(struct ps_list *l)
* own (typed) structures.
*/
#define ps_list_is_head(lh, o, lname) (ps_list_obj_get((lh), (o), lname) == (o))
#define ps_list_is_head(lh, o, lname) (ps_list_obj_get((lh), (o), lname) == (o))
/* functions for if we don't use the default name for the list field */
#define ps_list_singleton(o, lname) ps_list_ll_empty(&(o)->lname)
#define ps_list_init(o, lname) ps_list_ll_init(&(o)->lname)
#define ps_list_next(o, lname) ps_list_obj_get((o)->lname.n, (o), lname)
#define ps_list_prev(o, lname) ps_list_obj_get((o)->lname.p, (o), lname)
#define ps_list_add(o, n, lname) ps_list_ll_add(&(o)->lname, &(n)->lname)
#define ps_list_append(o, n, lname) ps_list_add(ps_list_prev((o), lname), n, lname)
#define ps_list_rem(o, lname) ps_list_ll_rem(&(o)->lname)
#define ps_list_head_add(lh, o, lname) ps_list_ll_add((&(lh)->l), &(o)->lname)
#define ps_list_singleton(o, lname) ps_list_ll_empty(&(o)->lname)
#define ps_list_init(o, lname) ps_list_ll_init(&(o)->lname)
#define ps_list_next(o, lname) ps_list_obj_get((o)->lname.n, (o), lname)
#define ps_list_prev(o, lname) ps_list_obj_get((o)->lname.p, (o), lname)
#define ps_list_add(o, n, lname) ps_list_ll_add(&(o)->lname, &(n)->lname)
#define ps_list_append(o, n, lname) ps_list_add(ps_list_prev((o), lname), n, lname)
#define ps_list_rem(o, lname) ps_list_ll_rem(&(o)->lname)
#define ps_list_head_add(lh, o, lname) ps_list_ll_add((&(lh)->l), &(o)->lname)
#define ps_list_head_append(lh, o, lname) ps_list_ll_add(((&(lh)->l)->p), &(o)->lname)
/**
@ -138,34 +144,31 @@ ps_list_ll_rem(struct ps_list *l)
* the name of the ps_list field in that type.
*/
#define ps_list_head_first(lh, type, lname) \
ps_container(((lh)->l.n), type, lname)
#define ps_list_head_last(lh, type, lname) \
ps_container(((lh)->l.p), type, lname)
#define ps_list_head_first(lh, type, lname) ps_container(((lh)->l.n), type, lname)
#define ps_list_head_last(lh, type, lname) ps_container(((lh)->l.p), type, lname)
/* If your struct named the list field "list" (as defined by PS_LIST_DEF_NAME */
#define ps_list_is_head_d(lh, o) ps_list_is_head(lh, o, PS_LIST_DEF_NAME)
#define ps_list_singleton_d(o) ps_list_singleton(o, PS_LIST_DEF_NAME)
#define ps_list_init_d(o) ps_list_init(o, PS_LIST_DEF_NAME)
#define ps_list_next_d(o) ps_list_next(o, PS_LIST_DEF_NAME)
#define ps_list_prev_d(o) ps_list_prev(o, PS_LIST_DEF_NAME)
#define ps_list_add_d(o, n) ps_list_add(o, n, PS_LIST_DEF_NAME)
#define ps_list_append_d(o, n) ps_list_append(o, n, PS_LIST_DEF_NAME)
#define ps_list_rem_d(o) ps_list_rem(o, PS_LIST_DEF_NAME)
#define ps_list_head_last_d(lh, o) ps_list_head_last(lh, o, PS_LIST_DEF_NAME)
#define ps_list_head_first_d(lh, type) ps_list_head_first(lh, type, PS_LIST_DEF_NAME)
#define ps_list_head_add_d(lh, o) ps_list_head_add(lh, o, PS_LIST_DEF_NAME)
#define ps_list_head_append_d(lh, o) ps_list_head_append(lh, o, PS_LIST_DEF_NAME)
#define ps_list_is_head_d(lh, o) ps_list_is_head(lh, o, PS_LIST_DEF_NAME)
#define ps_list_singleton_d(o) ps_list_singleton(o, PS_LIST_DEF_NAME)
#define ps_list_init_d(o) ps_list_init(o, PS_LIST_DEF_NAME)
#define ps_list_next_d(o) ps_list_next(o, PS_LIST_DEF_NAME)
#define ps_list_prev_d(o) ps_list_prev(o, PS_LIST_DEF_NAME)
#define ps_list_add_d(o, n) ps_list_add(o, n, PS_LIST_DEF_NAME)
#define ps_list_append_d(o, n) ps_list_append(o, n, PS_LIST_DEF_NAME)
#define ps_list_rem_d(o) ps_list_rem(o, PS_LIST_DEF_NAME)
#define ps_list_head_last_d(lh, o) ps_list_head_last(lh, o, PS_LIST_DEF_NAME)
#define ps_list_head_first_d(lh, type) ps_list_head_first(lh, type, PS_LIST_DEF_NAME)
#define ps_list_head_add_d(lh, o) ps_list_head_add(lh, o, PS_LIST_DEF_NAME)
#define ps_list_head_append_d(lh, o) ps_list_head_append(lh, o, PS_LIST_DEF_NAME)
/**
* Iteration API
*/
/* Iteration without mutating the list */
#define ps_list_foreach(head, iter, lname) \
for (iter = ps_list_head_first((head), __typeof__(*iter), lname) ; \
!ps_list_is_head((head), iter, lname) ; \
#define ps_list_foreach(head, iter, lname) \
for (iter = ps_list_head_first((head), __typeof__(*iter), lname); !ps_list_is_head((head), iter, lname); \
(iter) = ps_list_next(iter, lname))
#define ps_list_foreach_d(head, iter) ps_list_foreach(head, iter, PS_LIST_DEF_NAME)
@ -178,12 +181,10 @@ ps_list_ll_rem(struct ps_list *l)
*
* TODO: Add SMR/parallel version of this macro
*/
#define ps_list_foreach_del(head, iter, tmp, lname) \
for (iter = ps_list_head_first((head), __typeof__(*iter), lname), \
(tmp) = ps_list_next((iter), lname) ; \
!ps_list_is_head((head), iter, lname) ; \
(iter) = (tmp), (tmp) = ps_list_next((tmp), lname))
#define ps_list_foreach_del(head, iter, tmp, lname) \
for (iter = ps_list_head_first((head), __typeof__(*iter), lname), (tmp) = ps_list_next((iter), lname); \
!ps_list_is_head((head), iter, lname); (iter) = (tmp), (tmp) = ps_list_next((tmp), lname))
#define ps_list_foreach_del_d(head, iter, tmp) ps_list_foreach_del(head, iter, tmp, PS_LIST_DEF_NAME)
#endif /* PS_LIST_H */
#endif /* PS_LIST_H */

@ -9,8 +9,8 @@
// global queue for stealing (work-stealing-deque)
extern struct deque_sandbox *glb_dq;
extern pthread_mutex_t glbq_mtx;
extern int epfd;
extern pthread_mutex_t glbq_mtx;
extern int epfd;
void alloc_linear_memory(void);
void expand_memory(void);
@ -21,17 +21,18 @@ INLINE char *get_memory_ptr_for_runtime(u32 offset, u32 bounds_check);
static inline void *
get_memory_ptr_void(u32 offset, u32 bounds_check)
{
return (void*) get_memory_ptr_for_runtime(offset, bounds_check);
return (void *)get_memory_ptr_for_runtime(offset, bounds_check);
}
static inline char *
get_memory_string(u32 offset)
{
char *naive_ptr = get_memory_ptr_for_runtime(offset, 1);
int i = 0;
int i = 0;
while (1) {
// Keep bounds checking the waters over and over until we know it's safe (we find a terminating character)
// Keep bounds checking the waters over and over until we know it's safe (we find a terminating
// character)
char ith_element = get_memory_ptr_for_runtime(offset, i + 1)[i];
if (ith_element == '\0') return naive_ptr;
@ -50,15 +51,17 @@ void runtime_thd_init(void);
extern __thread uv_loop_t uvio;
static inline uv_loop_t *
runtime_uvio(void)
{ return &uvio; }
{
return &uvio;
}
static unsigned long long int
rdtsc(void)
{
unsigned long long int ret = 0;
unsigned int cycles_lo;
unsigned int cycles_hi;
__asm__ volatile ("RDTSC" : "=a" (cycles_lo), "=d" (cycles_hi));
unsigned int cycles_lo;
unsigned int cycles_hi;
__asm__ volatile("RDTSC" : "=a"(cycles_lo), "=d"(cycles_hi));
ret = (unsigned long long int)cycles_hi << 32 | cycles_lo;
return ret;

@ -11,17 +11,18 @@
#include <http.h>
struct io_handle {
int fd;
struct stat s_cache;
int fd;
struct stat s_cache;
union uv_any_handle uvh;
};
typedef enum {
typedef enum
{
SANDBOX_FREE,
SANDBOX_RUNNABLE,
SANDBOX_BLOCKED,
SANDBOX_WOKEN, //for race in block()/wakeup()
SANDBOX_RETURNED, //waiting for parent to read status?
SANDBOX_WOKEN, // for race in block()/wakeup()
SANDBOX_RETURNED, // waiting for parent to read status?
} sandbox_state_t;
/*
@ -34,54 +35,54 @@ struct sandbox {
sandbox_state_t state;
void *linear_start; // after sandbox struct
u32 linear_size; // from after sandbox struct
u32 linear_size; // from after sandbox struct
u32 linear_max_size;
u32 sb_size;
void *stack_start; // guess we need a mechanism for stack allocation.
u32 stack_size; // and to set the size of it.
arch_context_t ctxt; //register context for context switch.
arch_context_t ctxt; // register context for context switch.
// TODO: are all these necessary?
// TODO: are all these necessary?
u64 actual_deadline;
u64 expected_deadline;
u64 total_time;
u64 remaining_time;
u64 start_time;
struct module *mod; //which module is this an instance of?
struct module *mod; // which module is this an instance of?
i32 args_offset; //actual placement of args in the sandbox.
void *args; // args from request, must be of module->nargs size.
i32 retval;
i32 args_offset; // actual placement of args in the sandbox.
void *args; // args from request, must be of module->nargs size.
i32 retval;
struct io_handle handles[SBOX_MAX_OPEN];
#ifndef STANDALONE
struct sockaddr client; //client requesting connection!
int csock;
uv_tcp_t cuv;
uv_shutdown_t cuvsr;
http_parser hp;
struct http_request rqi;
struct sockaddr client; // client requesting connection!
int csock;
uv_tcp_t cuv;
uv_shutdown_t cuvsr;
http_parser hp;
struct http_request rqi;
struct http_response rsi;
#endif
char *read_buf;
char * read_buf;
ssize_t read_len, read_size;
struct ps_list list;
ssize_t rr_data_len; // <= max(mod->max_rr_sz)
char req_resp_data[1]; //of rr_data_sz, following sandbox mem..
ssize_t rr_data_len; // <= max(mod->max_rr_sz)
char req_resp_data[1]; // of rr_data_sz, following sandbox mem..
} PAGE_ALIGNED;
#ifndef STANDALONE
#ifdef SBOX_SCALE_ALLOC
struct sandbox_request {
struct module *mod;
char *args;
int sock;
struct module * mod;
char * args;
int sock;
struct sockaddr *addr;
};
typedef struct sandbox_request sbox_request_t;
@ -104,7 +105,7 @@ extern __thread struct sandbox *current_sandbox;
extern __thread arch_context_t *next_context;
typedef struct sandbox sandbox_t;
void sandbox_run(sbox_request_t *s);
void sandbox_run(sbox_request_t *s);
static inline sbox_request_t *
sbox_request_alloc(struct module *mod, char *args, int sock, const struct sockaddr *addr)
@ -113,7 +114,7 @@ sbox_request_alloc(struct module *mod, char *args, int sock, const struct sockad
#ifdef SBOX_SCALE_ALLOC
sbox_request_t *s = malloc(sizeof(sbox_request_t));
assert(s);
s->mod = mod;
s->mod = mod;
s->args = args;
s->sock = sock;
s->addr = (struct sockaddr *)addr;
@ -129,16 +130,18 @@ sbox_request_alloc(struct module *mod, char *args, int sock, const struct sockad
static inline struct sandbox *
sandbox_current(void)
{ return current_sandbox; }
{
return current_sandbox;
}
static inline void
sandbox_current_set(struct sandbox *sbox)
{
// FIXME: critical-section.
// FIXME: critical-section.
current_sandbox = sbox;
if (sbox == NULL) return;
sandbox_lmbase = sbox->linear_start;
sandbox_lmbase = sbox->linear_start;
sandbox_lmbound = sbox->linear_size;
// TODO: module table or sandbox table?
module_indirect_table = sbox->mod->indirect_table;
@ -171,7 +174,7 @@ sandbox_switch(struct sandbox *next)
softint_disable();
// switch sandbox (register context & base/bound/table)
struct sandbox *curr = sandbox_current();
arch_context_t *c = curr == NULL ? NULL : &curr->ctxt;
arch_context_t *c = curr == NULL ? NULL : &curr->ctxt;
sandbox_current_set(next);
if (curr && curr->state == SANDBOX_RETURNED) sandbox_local_end(curr);
// save current's registers and restore next's registers.
@ -191,22 +194,22 @@ sandbox_args(void)
return (char *)c->args;
}
//void sandbox_run(struct sandbox *s);
void *sandbox_run_func(void *data);
// void sandbox_run(struct sandbox *s);
void * sandbox_run_func(void *data);
struct sandbox *sandbox_schedule(int interrupt);
void sandbox_block(void);
void sandbox_wakeup(sandbox_t *sb);
// called in sandbox_entry() before and after fn() execution
void sandbox_block(void);
void sandbox_wakeup(sandbox_t *sb);
// called in sandbox_entry() before and after fn() execution
// for http request/response processing using uvio
void sandbox_block_http(void);
void sandbox_response(void);
// should be the entry-point for each sandbox so it can do per-sandbox mem/etc init.
// should have been called with stack allocated and sandbox_current() set!
void sandbox_entry(void);
void sandbox_exit(void);
void sandbox_entry(void);
void sandbox_exit(void);
extern struct deque_sandbox *glb_dq;
extern pthread_mutex_t glbq_mtx;
extern pthread_mutex_t glbq_mtx;
static inline int
sandbox_deque_push(sbox_request_t *s)
@ -260,7 +263,7 @@ static inline int
io_handle_preopen(void)
{
struct sandbox *s = sandbox_current();
int i;
int i;
for (i = 0; i < SBOX_MAX_OPEN; i++) {
if (s->handles[i].fd < 0) break;
}
@ -275,8 +278,8 @@ io_handle_open(int fd)
{
struct sandbox *s = sandbox_current();
if (fd < 0) return fd;
int i = io_handle_preopen();
s->handles[i].fd = fd; //well, per sandbox.. so synchronization necessary!
int i = io_handle_preopen();
s->handles[i].fd = fd; // well, per sandbox.. so synchronization necessary!
return i;
}

@ -9,7 +9,7 @@ static inline int
softint_mask(int sig)
{
sigset_t set;
int ret;
int ret;
assert(sig == SIGALRM || sig == SIGUSR1);
/* all threads created by the calling thread will have sig blocked */
@ -29,7 +29,7 @@ static inline int
softint_unmask(int sig)
{
sigset_t set;
int ret;
int ret;
assert(sig == SIGALRM || sig == SIGUSR1);
/* all threads created by the calling thread will have sig unblocked */
@ -50,7 +50,8 @@ extern __thread volatile sig_atomic_t softint_off;
static inline void
softint_disable(void)
{
while (__sync_bool_compare_and_swap(&softint_off, 0, 1) == false) ;
while (__sync_bool_compare_and_swap(&softint_off, 0, 1) == false)
;
}
static inline void

@ -17,53 +17,52 @@
#include <sys/stat.h>
#include <sys/uio.h>
#define EXPORT __attribute__ ((visibility ("default")))
#define IMPORT __attribute__ ((visibility ("default")))
#define EXPORT __attribute__((visibility("default")))
#define IMPORT __attribute__((visibility("default")))
#define INLINE __attribute__((always_inline))
#define WEAK __attribute__((weak))
#define WEAK __attribute__((weak))
#ifndef CACHELINE_SIZE
#define CACHELINE_SIZE 32
#endif
#ifndef PAGE_SIZE
#define PAGE_SIZE (1<<12)
#define PAGE_SIZE (1 << 12)
#endif
#define CACHE_ALIGNED __attribute__((aligned(CACHELINE_SIZE)))
#define PAGE_ALIGNED __attribute__((aligned(PAGE_SIZE)))
#define PAGE_ALIGNED __attribute__((aligned(PAGE_SIZE)))
/* For this family of macros, do NOT pass zero as the pow2 */
#define round_to_pow2(x, pow2) (((unsigned long)(x)) & (~((pow2)-1)))
#define round_to_pow2(x, pow2) (((unsigned long)(x)) & (~((pow2)-1)))
#define round_up_to_pow2(x, pow2) (round_to_pow2(((unsigned long)x) + (pow2)-1, (pow2)))
#define round_to_page(x) round_to_pow2(x, PAGE_SIZE)
#define round_to_page(x) round_to_pow2(x, PAGE_SIZE)
#define round_up_to_page(x) round_up_to_pow2(x, PAGE_SIZE)
// Type alias's so I don't have to write uint32_t a million times
typedef signed char i8;
typedef signed char i8;
typedef unsigned char u8;
typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
// FIXME: per-module configuration?
#define WASM_PAGE_SIZE (1024 * 64) //64KB
#define WASM_START_PAGES (1<<8) //16MB
#define WASM_MAX_PAGES (1<<15) //4GB
#define WASM_STACK_SIZE (1<<19) // 512KB.
#define SBOX_MAX_MEM (1L<<32) // 4GB
// These are per module symbols and I'd need to dlsym for each module. instead just use global constants, see above macros.
// The code generator compiles in the starting number of wasm pages, and the maximum number of pages
// If we try and allocate more than max_pages, we should fault
//extern u32 starting_pages;
//extern u32 max_pages;
#define WASM_PAGE_SIZE (1024 * 64) // 64KB
#define WASM_START_PAGES (1 << 8) // 16MB
#define WASM_MAX_PAGES (1 << 15) // 4GB
#define WASM_STACK_SIZE (1 << 19) // 512KB.
#define SBOX_MAX_MEM (1L << 32) // 4GB
// These are per module symbols and I'd need to dlsym for each module. instead just use global constants, see above
// macros. The code generator compiles in the starting number of wasm pages, and the maximum number of pages If we try
// and allocate more than max_pages, we should fault
// extern u32 starting_pages;
// extern u32 max_pages;
// The code generator also compiles in stubs that populate the linear memory and function table
void populate_memory(void);
@ -71,10 +70,10 @@ void populate_table(void);
// memory/* also provides the table access functions
// TODO: Change this to use a compiled in size
#define INDIRECT_TABLE_SIZE (1<<10)
#define INDIRECT_TABLE_SIZE (1 << 10)
struct indirect_table_entry {
u32 type_id;
u32 type_id;
void *func_pointer;
};
@ -82,8 +81,8 @@ extern __thread struct indirect_table_entry *module_indirect_table;
// for sandbox linear memory isolation
extern __thread void *sandbox_lmbase;
extern __thread u32 sandbox_lmbound;
extern i32 logfd;
extern __thread u32 sandbox_lmbound;
extern i32 logfd;
// functions in the module to lookup and call per sandbox.
typedef i32 (*mod_main_fn_t)(i32 a, i32 b);
@ -92,7 +91,8 @@ typedef void (*mod_mem_fn_t)(void);
typedef void (*mod_tbl_fn_t)(void);
typedef void (*mod_libc_fn_t)(i32, i32);
typedef enum {
typedef enum
{
MOD_ARG_MODPATH = 0,
MOD_ARG_MODPORT,
MOD_ARG_MODNAME,
@ -118,20 +118,20 @@ typedef enum {
// FIXME: some naive work-stealing here..
#define SBOX_PULL_MAX 1
#define SBOX_MAX_OPEN 32
#define SBOX_MAX_OPEN 32
#define SBOX_PREOPEN_MAGIC (707707707) // reads lol lol lol upside down
#define SOFTINT_TIMER_START_USEC (10*1000) //start timers 10 ms from now.
#define SOFTINT_TIMER_PERIOD_USEC (1000*5) // 100ms timer..
#define SOFTINT_TIMER_START_USEC (10 * 1000) // start timers 10 ms from now.
#define SOFTINT_TIMER_PERIOD_USEC (1000 * 5) // 100ms timer..
#ifdef DEBUG
#ifdef NOSTDIO
#define debuglog(fmt,...) dprintf(logfd, "(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ## __VA_ARGS__)
#define debuglog(fmt, ...) dprintf(logfd, "(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__)
#else
#define debuglog(fmt,...) printf("(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ## __VA_ARGS__)
#define debuglog(fmt, ...) printf("(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__)
#endif
#else
#define debuglog(fmt,...)
#define debuglog(fmt, ...)
#endif
#define GLB_STDOUT "/dev/null"
@ -142,24 +142,24 @@ typedef enum {
#define RDWR_VEC_MAX 16
#define MOD_REQ_CORE 0 // core dedicated to check module requests..
#define SBOX_NCORES (NCORES > 1 ? NCORES - 1 : NCORES) // number of sandboxing threads
#define SBOX_MAX_REQS (1<<19) //random!
#define MOD_REQ_CORE 0 // core dedicated to check module requests..
#define SBOX_NCORES (NCORES > 1 ? NCORES - 1 : NCORES) // number of sandboxing threads
#define SBOX_MAX_REQS (1 << 19) // random!
#define SBOX_RESP_STRSZ 32
#define MOD_BACKLOG 1000
#define EPOLL_MAX 1024
#define MOD_BACKLOG 1000
#define EPOLL_MAX 1024
#define MOD_REQ_RESP_DEFAULT (PAGE_SIZE)
#define QUIESCENSE_TIME (1<<20) //cycles!
#define QUIESCENSE_TIME (1 << 20) // cycles!
#define HTTP_HEADERS_MAX 16
#define HTTP_HEADER_MAXSZ 32
#define HTTP_HEADERVAL_MAXSZ 64
#define HTTP_RESP_200OK "HTTP/1.1 200 OK\r\n"
#define HTTP_RESP_CONTTYPE "Content-type: \r\n"
#define HTTP_RESP_CONTLEN "Content-length: \r\n\r\n" //content body follows this
#define HTTP_RESP_200OK "HTTP/1.1 200 OK\r\n"
#define HTTP_RESP_CONTTYPE "Content-type: \r\n"
#define HTTP_RESP_CONTLEN "Content-length: \r\n\r\n" // content body follows this
#define HTTP_RESP_CONTTYPE_PLAIN "text/plain"
#endif /* SFRT_TYPES_H */

@ -7,7 +7,7 @@
/* perhaps move it to module.h or sandbox.h? */
struct sandbox *util_parse_sandbox_string_custom(struct module *m, char *str, const struct sockaddr *addr);
struct sandbox *util_parse_sandbox_string_json(struct module *m, char *str, const struct sockaddr *addr);
int util_parse_modules_file_json(char *filename);
int util_parse_modules_file_custom(char *filename);
int util_parse_modules_file_json(char *filename);
int util_parse_modules_file_custom(char *filename);
#endif /* SFRT_UTIL_H */

@ -6,7 +6,7 @@ extern i32 inner_syscall_handler(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f
i32
env_syscall_handler(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f)
{
i32 i = inner_syscall_handler(n, a, b, c, d, e, f);
i32 i = inner_syscall_handler(n, a, b, c, d, e, f);
return i;
}
@ -22,12 +22,12 @@ env___syscall(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f)
i32
env_a_ctz_64(u64 x)
{
__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
__asm__("bsf %1,%0" : "=r"(x) : "r"(x));
return x;
}
//static inline int a_ctz_l(unsigned long x)
// static inline int a_ctz_l(unsigned long x)
//{
// __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
// return x;
@ -36,7 +36,7 @@ env_a_ctz_64(u64 x)
INLINE void
env_a_and_64(i32 p_off, u64 v)
{
uint64_t* p = get_memory_ptr_void(p_off, sizeof(uint64_t));
uint64_t *p = get_memory_ptr_void(p_off, sizeof(uint64_t));
*p &= v;
// __asm__( "lock ; and %1, %0"
@ -47,20 +47,20 @@ INLINE void
env_a_or_64(i32 p_off, i64 v)
{
assert(sizeof(i64) == sizeof(uint64_t));
uint64_t* p = get_memory_ptr_void(p_off, sizeof(i64));
uint64_t *p = 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)
// 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)
// 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" );
@ -71,10 +71,9 @@ i32
env_a_cas(i32 p_off, i32 t, i32 s)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int* p = get_memory_ptr_void(p_off, sizeof(i32));
volatile int *p = get_memory_ptr_void(p_off, sizeof(i32));
__asm__( "lock ; cmpxchg %3, %1"
: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
__asm__("lock ; cmpxchg %3, %1" : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory");
return t;
}
@ -83,12 +82,11 @@ void
env_a_or(i32 p_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int* p = get_memory_ptr_void(p_off, sizeof(i32));
__asm__( "lock ; or %1, %0"
: "=m"(*p) : "r"(v) : "memory" );
volatile int *p = 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)
// static inline void a_and(volatile int *p, int v)
//{
// __asm__( "lock ; and %1, %0"
// : "=m"(*p) : "r"(v) : "memory" );
@ -98,9 +96,9 @@ i32
env_a_swap(i32 x_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int* x = get_memory_ptr_void(x_off, sizeof(i32));
volatile int *x = get_memory_ptr_void(x_off, sizeof(i32));
__asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
__asm__("xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
@ -109,9 +107,9 @@ i32
env_a_fetch_add(i32 x_off, i32 v)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int* x = get_memory_ptr_void(x_off, sizeof(i32));
volatile int *x = get_memory_ptr_void(x_off, sizeof(i32));
__asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
__asm__("lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory");
return v;
}
@ -120,33 +118,32 @@ void
env_a_inc(i32 x_off)
{
assert(sizeof(i32) == sizeof(volatile int));
volatile int* x = get_memory_ptr_void(x_off, sizeof(i32));
volatile int *x = get_memory_ptr_void(x_off, sizeof(i32));
__asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
__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 = get_memory_ptr_void(x_off, sizeof(i32));
volatile int *x = get_memory_ptr_void(x_off, sizeof(i32));
__asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
__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 = get_memory_ptr_void(p_off, sizeof(i32));
__asm__ __volatile__(
"mov %1, %0 ; lock ; orl $0,(%%esp)" : "=m"(*p) : "r"(x) : "memory" );
volatile int *p = 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" );
__asm__ __volatile__("pause" : : : "memory");
}
void
@ -159,7 +156,7 @@ env_do_crash(i32 i)
int
env_a_ctz_32(i32 x)
{
__asm__( "bsf %1,%0" : "=r"(x) : "r"(x) );
__asm__("bsf %1,%0" : "=r"(x) : "r"(x));
return x;
}
@ -167,7 +164,7 @@ env_a_ctz_32(i32 x)
void
env_do_barrier(i32 x)
{
__asm__ __volatile__( "" : : : "memory" );
__asm__ __volatile__("" : : : "memory");
}

@ -9,11 +9,11 @@ static inline int
http_on_msg_begin(http_parser *parser)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
r->message_begin = 1;
r->last_was_value = 1; //should always start with a header..
r->message_begin = 1;
r->last_was_value = 1; // should always start with a header..
#endif
return 0;
}
@ -22,7 +22,7 @@ static inline int
http_on_msg_end(http_parser *parser)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
r->message_end = 1;
@ -34,7 +34,7 @@ static inline int
http_on_header_end(http_parser *parser)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
r->header_end = 1;
@ -43,10 +43,10 @@ http_on_header_end(http_parser *parser)
}
static inline int
http_on_url(http_parser* parser, const char *at, size_t length)
http_on_url(http_parser *parser, const char *at, size_t length)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
assert(strncmp(s->mod->name, (at + 1), length - 1) == 0);
@ -55,55 +55,57 @@ http_on_url(http_parser* parser, const char *at, size_t length)
}
static inline int
http_on_header_field(http_parser* parser, const char *at, size_t length)
http_on_header_field(http_parser *parser, const char *at, size_t length)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
if (r->last_was_value) r->nheaders ++;
if (r->last_was_value) r->nheaders++;
assert(r->nheaders <= HTTP_HEADERS_MAX);
assert(length < HTTP_HEADER_MAXSZ);
r->last_was_value = 0;
r->headers[r->nheaders - 1].key = (char *)at; //it is from the sandbox's req_resp_data, should persist.
r->last_was_value = 0;
r->headers[r->nheaders - 1].key = (char *)at; // it is from the sandbox's req_resp_data, should persist.
#endif
return 0;
}
static inline int
http_on_header_value(http_parser* parser, const char *at, size_t length)
http_on_header_value(http_parser *parser, const char *at, size_t length)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
r->last_was_value = 1;
assert(r->nheaders <= HTTP_HEADERS_MAX);
assert(length < HTTP_HEADERVAL_MAXSZ);
r->headers[r->nheaders - 1].val = (char *)at; //it is from the sandbox's req_resp_data, should persist.
r->headers[r->nheaders - 1].val = (char *)at; // it is from the sandbox's req_resp_data, should persist.
#endif
return 0;
return 0;
}
static inline int
http_on_body(http_parser* parser, const char *at, size_t length)
http_on_body(http_parser *parser, const char *at, size_t length)
{
#ifndef STANDALONE
struct sandbox *s = parser->data;
struct sandbox * s = parser->data;
struct http_request *r = &s->rqi;
assert(r->bodylen + length <= s->mod->max_req_sz);
if (!r->body) r->body = (char *)at;
else assert(r->body + r->bodylen == at);
assert(r->bodylen + length <= s->mod->max_req_sz);
if (!r->body)
r->body = (char *)at;
else
assert(r->body + r->bodylen == at);
r->bodylen += length;
r->bodylen += length;
#endif
return 0;
return 0;
}
int
@ -128,8 +130,8 @@ http_response_header_set_sb(struct sandbox *c, char *key, int len)
assert(r->nheaders < HTTP_HEADERS_MAX);
r->nheaders++;
r->headers[r->nheaders-1].hdr = key;
r->headers[r->nheaders-1].len = len;
r->headers[r->nheaders - 1].hdr = key;
r->headers[r->nheaders - 1].len = len;
#endif
return 0;
@ -142,7 +144,7 @@ http_response_body_set_sb(struct sandbox *c, char *body, int len)
struct http_response *r = &c->rsi;
assert(len <= c->mod->max_resp_sz);
r->body = body;
r->body = body;
r->bodylen = len;
#endif
@ -156,7 +158,7 @@ http_response_status_set_sb(struct sandbox *c, char *status, int len)
struct http_response *r = &c->rsi;
r->status = status;
r->stlen = len;
r->stlen = len;
#endif
return 0;
@ -181,7 +183,7 @@ http_response_vector_sb(struct sandbox *c)
if (r->body) {
r->bufs[nb] = uv_buf_init(r->body, r->bodylen);
nb++;
r->bufs[nb] = uv_buf_init(r->status + r->stlen - 2, 2); //for crlf
r->bufs[nb] = uv_buf_init(r->status + r->stlen - 2, 2); // for crlf
nb++;
}
#else
@ -206,7 +208,7 @@ http_response_vector_sb(struct sandbox *c)
}
#endif
#endif
return nb;
}
@ -223,10 +225,10 @@ void
http_init(void)
{
http_parser_settings_init(&settings);
settings.on_url = http_on_url;
settings.on_header_field = http_on_header_field;
settings.on_header_value = http_on_header_value;
settings.on_body = http_on_body;
settings.on_url = http_on_url;
settings.on_header_field = http_on_header_field;
settings.on_header_value = http_on_header_value;
settings.on_body = http_on_body;
settings.on_headers_complete = http_on_header_end;
settings.on_message_begin = http_on_msg_begin;
settings.on_message_complete = http_on_msg_end;

@ -11,25 +11,25 @@
#define GID 0xFE
// Elf auxilary vector values (see google for what those are)
#define AT_NULL 0
#define AT_IGNORE 1
#define AT_EXECFD 2
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_BASE 7
#define AT_FLAGS 8
#define AT_ENTRY 9
#define AT_NOTELF 10
#define AT_UID 11
#define AT_EUID 12
#define AT_GID 13
#define AT_EGID 14
#define AT_CLKTCK 17
#define AT_SECURE 23
#define AT_NULL 0
#define AT_IGNORE 1
#define AT_EXECFD 2
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_BASE 7
#define AT_FLAGS 8
#define AT_ENTRY 9
#define AT_NOTELF 10
#define AT_UID 11
#define AT_EUID 12
#define AT_GID 13
#define AT_EGID 14
#define AT_CLKTCK 17
#define AT_SECURE 23
#define AT_BASE_PLATFORM 24
#define AT_RANDOM 25
#define AT_RANDOM 25
// offset = a WASM ptr to memory the runtime can use
void
@ -61,7 +61,7 @@ stub_init(i32 offset)
AT_SECURE,
0,
AT_RANDOM,
(i32) rand(), // It's pretty stupid to use rand here, but w/e
(i32)rand(), // It's pretty stupid to use rand here, but w/e
0,
};
i32 env_vec_offset = offset;
@ -77,11 +77,11 @@ stub_init(i32 offset)
u32
wasm_read(i32 filedes, i32 buf_offset, i32 nbyte)
{
char* buf = get_memory_ptr_void(buf_offset, nbyte);
i32 res = (i32) read(filedes, buf, nbyte);
char *buf = get_memory_ptr_void(buf_offset, nbyte);
i32 res = (i32)read(filedes, buf, nbyte);
if (res == -1) return -errno;
return res;
}
@ -89,36 +89,36 @@ wasm_read(i32 filedes, i32 buf_offset, i32 nbyte)
i32
wasm_write(i32 fd, i32 buf_offset, i32 buf_size)
{
char* buf = get_memory_ptr_void(buf_offset, buf_size);
i32 res = (i32) write(fd, buf, buf_size);
char *buf = get_memory_ptr_void(buf_offset, buf_size);
i32 res = (i32)write(fd, buf, buf_size);
if (res == -1) return -errno;
return res;
}
#define WO_RDONLY 00
#define WO_WRONLY 01
#define WO_RDWR 02
#define WO_CREAT 0100
#define WO_EXCL 0200
#define WO_NOCTTY 0400
#define WO_TRUNC 01000
#define WO_APPEND 02000
#define WO_NONBLOCK 04000
#define WO_DSYNC 010000
#define WO_SYNC 04010000
#define WO_RSYNC 04010000
#define WO_RDONLY 00
#define WO_WRONLY 01
#define WO_RDWR 02
#define WO_CREAT 0100
#define WO_EXCL 0200
#define WO_NOCTTY 0400
#define WO_TRUNC 01000
#define WO_APPEND 02000
#define WO_NONBLOCK 04000
#define WO_DSYNC 010000
#define WO_SYNC 04010000
#define WO_RSYNC 04010000
#define WO_DIRECTORY 0200000
#define WO_NOFOLLOW 0400000
#define WO_CLOEXEC 02000000
#define WO_CLOEXEC 02000000
#define SYS_OPEN 2
i32
wasm_open(i32 path_off, i32 flags, i32 mode)
{
char* path = get_memory_string(path_off);
char *path = get_memory_string(path_off);
i32 modified_flags = 0;
@ -152,19 +152,18 @@ wasm_open(i32 path_off, i32 flags, i32 mode)
flags ^= WO_EXCL;
}
i32 res = (i32) open(path, modified_flags, mode);
i32 res = (i32)open(path, modified_flags, mode);
if (res == -1) return -errno;
return res;
}
#define SYS_CLOSE 3
i32
wasm_close(i32 fd)
{
i32 res = (i32) close(fd);
i32 res = (i32)close(fd);
if (res == -1) return -errno;
@ -186,9 +185,18 @@ struct wasm_stat {
i32 st_blksize;
i64 st_blocks;
struct { i32 tv_sec; i32 tv_nsec; } st_atim;
struct { i32 tv_sec; i32 tv_nsec; } st_mtim;
struct { i32 tv_sec; i32 tv_nsec; } st_ctim;
struct {
i32 tv_sec;
i32 tv_nsec;
} st_atim;
struct {
i32 tv_sec;
i32 tv_nsec;
} st_mtim;
struct {
i32 tv_sec;
i32 tv_nsec;
} st_ctim;
i32 __pad1[3];
};
@ -215,42 +223,42 @@ struct wasm_stat {
i32
wasm_stat(u32 path_str_offset, i32 stat_offset)
{
char *path = get_memory_string(path_str_offset);
struct wasm_stat* stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
char * path = get_memory_string(path_str_offset);
struct wasm_stat *stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
struct stat stat;
i32 res = lstat(path, &stat);
i32 res = lstat(path, &stat);
if (res == -1) return -errno;
*stat_ptr = (struct wasm_stat) {
.st_dev = stat.st_dev,
.st_ino = stat.st_ino,
.st_nlink = stat.st_nlink,
.st_mode = stat.st_mode,
.st_uid = stat.st_uid,
.st_gid = stat.st_gid,
.st_rdev = stat.st_rdev,
.st_size = stat.st_size,
.st_blksize = stat.st_blksize,
.st_blocks = stat.st_blocks,
*stat_ptr = (struct wasm_stat){
.st_dev = stat.st_dev,
.st_ino = stat.st_ino,
.st_nlink = stat.st_nlink,
.st_mode = stat.st_mode,
.st_uid = stat.st_uid,
.st_gid = stat.st_gid,
.st_rdev = stat.st_rdev,
.st_size = stat.st_size,
.st_blksize = stat.st_blksize,
.st_blocks = stat.st_blocks,
};
#ifdef __APPLE__
stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec;
stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec;
stat_ptr->st_atim.tv_nsec = stat.st_atimespec.tv_nsec;
stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec;
stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec;
stat_ptr->st_mtim.tv_nsec = stat.st_mtimespec.tv_nsec;
stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec;
stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec;
stat_ptr->st_ctim.tv_nsec = stat.st_ctimespec.tv_nsec;
#else
stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec;
stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec;
stat_ptr->st_atim.tv_nsec = stat.st_atim.tv_nsec;
stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec;
stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec;
stat_ptr->st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec;
stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec;
stat_ptr->st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
#endif
@ -261,41 +269,41 @@ wasm_stat(u32 path_str_offset, i32 stat_offset)
i32
wasm_fstat(i32 filedes, i32 stat_offset)
{
struct wasm_stat* stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
struct wasm_stat *stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
struct stat stat;
i32 res = fstat(filedes, &stat);
i32 res = fstat(filedes, &stat);
if (res == -1) return -errno;
*stat_ptr = (struct wasm_stat) {
.st_dev = stat.st_dev,
.st_ino = stat.st_ino,
.st_nlink = stat.st_nlink,
.st_mode = stat.st_mode,
.st_uid = stat.st_uid,
.st_gid = stat.st_gid,
.st_rdev = stat.st_rdev,
.st_size = stat.st_size,
.st_blksize = stat.st_blksize,
.st_blocks = stat.st_blocks,
*stat_ptr = (struct wasm_stat){
.st_dev = stat.st_dev,
.st_ino = stat.st_ino,
.st_nlink = stat.st_nlink,
.st_mode = stat.st_mode,
.st_uid = stat.st_uid,
.st_gid = stat.st_gid,
.st_rdev = stat.st_rdev,
.st_size = stat.st_size,
.st_blksize = stat.st_blksize,
.st_blocks = stat.st_blocks,
};
#ifdef __APPLE__
stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec;
stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec;
stat_ptr->st_atim.tv_nsec = stat.st_atimespec.tv_nsec;
stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec;
stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec;
stat_ptr->st_mtim.tv_nsec = stat.st_mtimespec.tv_nsec;
stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec;
stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec;
stat_ptr->st_ctim.tv_nsec = stat.st_ctimespec.tv_nsec;
#else
stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec;
stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec;
stat_ptr->st_atim.tv_nsec = stat.st_atim.tv_nsec;
stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec;
stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec;
stat_ptr->st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec;
stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec;
stat_ptr->st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
#endif
@ -306,42 +314,42 @@ wasm_fstat(i32 filedes, i32 stat_offset)
i32
wasm_lstat(i32 path_str_offset, i32 stat_offset)
{
char *path = get_memory_string(path_str_offset);
struct wasm_stat* stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
char * path = get_memory_string(path_str_offset);
struct wasm_stat *stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
struct stat stat;
i32 res = lstat(path, &stat);
i32 res = lstat(path, &stat);
if (res == -1) return -errno;
*stat_ptr = (struct wasm_stat) {
.st_dev = stat.st_dev,
.st_ino = stat.st_ino,
.st_nlink = stat.st_nlink,
.st_mode = stat.st_mode,
.st_uid = stat.st_uid,
.st_gid = stat.st_gid,
.st_rdev = stat.st_rdev,
.st_size = stat.st_size,
.st_blksize = stat.st_blksize,
.st_blocks = stat.st_blocks,
*stat_ptr = (struct wasm_stat){
.st_dev = stat.st_dev,
.st_ino = stat.st_ino,
.st_nlink = stat.st_nlink,
.st_mode = stat.st_mode,
.st_uid = stat.st_uid,
.st_gid = stat.st_gid,
.st_rdev = stat.st_rdev,
.st_size = stat.st_size,
.st_blksize = stat.st_blksize,
.st_blocks = stat.st_blocks,
};
#ifdef __APPLE__
stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec;
stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec;
stat_ptr->st_atim.tv_nsec = stat.st_atimespec.tv_nsec;
stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec;
stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec;
stat_ptr->st_mtim.tv_nsec = stat.st_mtimespec.tv_nsec;
stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec;
stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec;
stat_ptr->st_ctim.tv_nsec = stat.st_ctimespec.tv_nsec;
#else
stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec;
stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec;
stat_ptr->st_atim.tv_nsec = stat.st_atim.tv_nsec;
stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec;
stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec;
stat_ptr->st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec;
stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec;
stat_ptr->st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
#endif
@ -353,7 +361,7 @@ wasm_lstat(i32 path_str_offset, i32 stat_offset)
i32
wasm_lseek(i32 filedes, i32 file_offset, i32 whence)
{
i32 res = (i32) lseek(filedes, file_offset, whence);
i32 res = (i32)lseek(filedes, file_offset, whence);
if (res == -1) return -errno;
@ -377,9 +385,7 @@ wasm_mmap(i32 addr, i32 len, i32 prot, i32 flags, i32 fd, i32 offset)
assert(len % WASM_PAGE_SIZE == 0);
i32 result = sandbox_lmbound;
for (int i = 0; i < len / WASM_PAGE_SIZE; i++) {
expand_memory();
}
for (int i = 0; i < len / WASM_PAGE_SIZE; i++) { expand_memory(); }
return result;
}
@ -410,11 +416,9 @@ struct wasm_iovec {
i32
wasm_readv(i32 fd, i32 iov_offset, i32 iovcnt)
{
i32 read = 0;
struct wasm_iovec *iov = get_memory_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec));
for (int i = 0; i < iovcnt; i++) {
read += wasm_read(fd, iov[i].base_offset, iov[i].len);
}
i32 read = 0;
struct wasm_iovec *iov = get_memory_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec));
for (int i = 0; i < iovcnt; i++) { read += wasm_read(fd, iov[i].base_offset, iov[i].len); }
return read;
}
@ -430,8 +434,8 @@ wasm_writev(i32 fd, i32 iov_offset, i32 iovcnt)
if (fd == 1) {
int sum = 0;
for (int i = 0; i < iovcnt; i++) {
i32 len = iov[i].len;
void* ptr = get_memory_ptr_void(iov[i].base_offset, len);
i32 len = iov[i].len;
void *ptr = get_memory_ptr_void(iov[i].base_offset, len);
printf("%.*s", len, ptr);
sum += len;
@ -442,12 +446,12 @@ wasm_writev(i32 fd, i32 iov_offset, i32 iovcnt)
struct iovec vecs[iovcnt];
for (int i = 0; i < iovcnt; i++) {
i32 len = iov[i].len;
void* ptr = get_memory_ptr_void(iov[i].base_offset, len);
vecs[i] = (struct iovec) {ptr, len};
i32 len = iov[i].len;
void *ptr = get_memory_ptr_void(iov[i].base_offset, len);
vecs[i] = (struct iovec){ ptr, len };
}
i32 res = (i32) writev(fd, vecs, iovcnt);
i32 res = (i32)writev(fd, vecs, iovcnt);
if (res == -1) return -errno;
return res;
@ -459,23 +463,23 @@ wasm_writev(i32 fd, i32 iov_offset, i32 iovcnt)
u32
wasm_getpid()
{
return (u32) getpid();
return (u32)getpid();
}
#define WF_DUPFD 0
#define WF_GETFD 1
#define WF_SETFD 2
#define WF_GETFL 3
#define WF_SETFL 4
#define WF_DUPFD 0
#define WF_GETFD 1
#define WF_SETFD 2
#define WF_GETFL 3
#define WF_SETFL 4
#define WF_SETOWN 8
#define WF_GETOWN 9
#define WF_SETSIG 10
#define WF_GETSIG 11
#define WF_GETLK 5
#define WF_SETLK 6
#define WF_GETLK 5
#define WF_SETLK 6
#define WF_SETLKW 7
#define SYS_FCNTL 72
@ -483,15 +487,14 @@ u32
wasm_fcntl(u32 fd, u32 cmd, u32 arg_or_lock_ptr)
{
switch (cmd) {
case WF_SETFD:
// return fcntl(fd, F_SETFD, arg_or_lock_ptr);
return 0;
case WF_SETLK:
return 0;
default:
assert(0);
case WF_SETFD:
// return fcntl(fd, F_SETFD, arg_or_lock_ptr);
return 0;
case WF_SETLK:
return 0;
default:
assert(0);
}
}
#define SYS_FSYNC 74
@ -508,8 +511,8 @@ wasm_fsync(u32 filedes)
u32
wasm_getcwd(u32 buf_offset, u32 buf_size)
{
char* buf = get_memory_ptr_void(buf_offset, buf_size);
char* res = getcwd(buf, buf_size);
char *buf = get_memory_ptr_void(buf_offset, buf_size);
char *res = getcwd(buf, buf_size);
if (!res) return 0;
return buf_offset;
@ -519,8 +522,8 @@ wasm_getcwd(u32 buf_offset, u32 buf_size)
u32
wasm_unlink(u32 path_str_offset)
{
char* str = get_memory_string(path_str_offset);
u32 res = unlink(str);
char *str = get_memory_string(path_str_offset);
u32 res = unlink(str);
if (res == -1) return -errno;
return 0;
@ -530,7 +533,7 @@ wasm_unlink(u32 path_str_offset)
u32
wasm_geteuid()
{
return (u32) geteuid();
return (u32)geteuid();
}
#define SYS_SET_THREAD_AREA 205
@ -548,26 +551,26 @@ wasm_get_time(i32 clock_id, i32 timespec_off)
{
clockid_t real_clock;
switch (clock_id) {
case 0:
real_clock = CLOCK_REALTIME;
break;
case 1:
real_clock = CLOCK_MONOTONIC;
break;
case 2:
real_clock = CLOCK_PROCESS_CPUTIME_ID;
break;
default:
assert(0);
case 0:
real_clock = CLOCK_REALTIME;
break;
case 1:
real_clock = CLOCK_MONOTONIC;
break;
case 2:
real_clock = CLOCK_PROCESS_CPUTIME_ID;
break;
default:
assert(0);
}
struct wasm_time_spec* timespec = get_memory_ptr_void(timespec_off, sizeof(struct wasm_time_spec));
struct wasm_time_spec *timespec = get_memory_ptr_void(timespec_off, sizeof(struct wasm_time_spec));
struct timespec native_timespec = { 0, 0 };
int res = clock_gettime(real_clock, &native_timespec);
int res = clock_gettime(real_clock, &native_timespec);
if (res == -1) return -errno;
timespec->sec = native_timespec.tv_sec;
timespec->sec = native_timespec.tv_sec;
timespec->nanosec = native_timespec.tv_nsec;
return res;
@ -589,11 +592,11 @@ wasm_fchown(i32 fd, u32 owner, u32 group)
}
// networking syscalls
#define SYS_SOCKET 41
#define SYS_SOCKET 41
#define SYS_CONNECT 42
#define SYS_ACCEPT 43
#define SYS_BIND 49
#define SYS_LISTEN 50
#define SYS_ACCEPT 43
#define SYS_BIND 49
#define SYS_LISTEN 50
i32
wasm_socket(i32 domain, i32 type, i32 protocol)
{
@ -626,13 +629,13 @@ wasm_listen(i32 sockfd, i32 backlog)
return listen(sockfd, backlog);
}
#define SYS_SENDTO 44
#define SYS_SENDTO 44
#define SYS_RECVFROM 45
i32
wasm_sendto(i32 fd, i32 buff_offset, i32 len, i32 flags, i32 sockaddr_offset, i32 sockaddr_len)
{
char *buf = get_memory_ptr_void(buff_offset, len);
char * buf = get_memory_ptr_void(buff_offset, len);
struct sockaddr *addr = sockaddr_len ? get_memory_ptr_void(sockaddr_offset, sockaddr_len) : NULL;
return sendto(fd, buf, len, flags, addr, sockaddr_len);
@ -641,8 +644,8 @@ wasm_sendto(i32 fd, i32 buff_offset, i32 len, i32 flags, i32 sockaddr_offset, i3
i32
wasm_recvfrom(i32 fd, i32 buff_offset, i32 size, i32 flags, i32 sockaddr_offset, i32 socklen_offset)
{
char *buf = get_memory_ptr_void(buff_offset, size);
socklen_t *len = get_memory_ptr_void(socklen_offset, sizeof(socklen_t));
char * buf = get_memory_ptr_void(buff_offset, size);
socklen_t * len = get_memory_ptr_void(socklen_offset, sizeof(socklen_t));
struct sockaddr *addr = *len ? get_memory_ptr_void(sockaddr_offset, *len) : NULL;
return recvfrom(fd, buf, size, flags, addr, addr ? len : NULL);
@ -652,43 +655,78 @@ i32
inner_syscall_handler(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f)
{
i32 res;
switch(n) {
case SYS_READ: return wasm_read(a, b, c);
case SYS_WRITE: return wasm_write(a, b, c);
case SYS_OPEN: return wasm_open(a, b, c);
case SYS_CLOSE: return wasm_close(a);
case SYS_STAT: return wasm_stat(a, b);
case SYS_FSTAT: return wasm_fstat(a, b);
case SYS_LSTAT: return wasm_lstat(a, b);
case SYS_LSEEK: return wasm_lseek(a, b, c);
case SYS_MMAP: return wasm_mmap(a, b, c, d, e, f);
case SYS_MUNMAP: return 0;
case SYS_BRK: return 0;
case SYS_RT_SIGACTION: return 0;
case SYS_RT_SIGPROGMASK: return 0;
case SYS_IOCTL: return wasm_ioctl(a, b, c);
case SYS_READV: return wasm_readv(a, b, c);
case SYS_WRITEV: return wasm_writev(a, b, c);
case SYS_MADVISE: return 0;
case SYS_GETPID: return wasm_getpid();
case SYS_FCNTL: return wasm_fcntl(a, b, c);
case SYS_FSYNC: return wasm_fsync(a);
case SYS_UNLINK: return wasm_unlink(a);
case SYS_GETCWD: return wasm_getcwd(a, b);
case SYS_GETEUID: return wasm_geteuid();
case SYS_SET_THREAD_AREA: return 0;
case SYS_SET_TID_ADDRESS: return 0;
case SYS_GET_TIME: return wasm_get_time(a, b);
case SYS_EXIT_GROUP: return wasm_exit_group(a);
case SYS_FCHOWN: return wasm_fchown(a, b, c);
case SYS_SOCKET: return wasm_socket(a, b, c);
case SYS_CONNECT: return wasm_connect(a, b, c);
case SYS_ACCEPT: return wasm_accept(a, b, c);
case SYS_BIND: return wasm_bind(a, b, c);
case SYS_LISTEN: return wasm_listen(a, b);
case SYS_SENDTO: return wasm_sendto(a, b, c, d, e, f);
case SYS_RECVFROM: return wasm_recvfrom(a, b, c, d, e, f);
switch (n) {
case SYS_READ:
return wasm_read(a, b, c);
case SYS_WRITE:
return wasm_write(a, b, c);
case SYS_OPEN:
return wasm_open(a, b, c);
case SYS_CLOSE:
return wasm_close(a);
case SYS_STAT:
return wasm_stat(a, b);
case SYS_FSTAT:
return wasm_fstat(a, b);
case SYS_LSTAT:
return wasm_lstat(a, b);
case SYS_LSEEK:
return wasm_lseek(a, b, c);
case SYS_MMAP:
return wasm_mmap(a, b, c, d, e, f);
case SYS_MUNMAP:
return 0;
case SYS_BRK:
return 0;
case SYS_RT_SIGACTION:
return 0;
case SYS_RT_SIGPROGMASK:
return 0;
case SYS_IOCTL:
return wasm_ioctl(a, b, c);
case SYS_READV:
return wasm_readv(a, b, c);
case SYS_WRITEV:
return wasm_writev(a, b, c);
case SYS_MADVISE:
return 0;
case SYS_GETPID:
return wasm_getpid();
case SYS_FCNTL:
return wasm_fcntl(a, b, c);
case SYS_FSYNC:
return wasm_fsync(a);
case SYS_UNLINK:
return wasm_unlink(a);
case SYS_GETCWD:
return wasm_getcwd(a, b);
case SYS_GETEUID:
return wasm_geteuid();
case SYS_SET_THREAD_AREA:
return 0;
case SYS_SET_TID_ADDRESS:
return 0;
case SYS_GET_TIME:
return wasm_get_time(a, b);
case SYS_EXIT_GROUP:
return wasm_exit_group(a);
case SYS_FCHOWN:
return wasm_fchown(a, b, c);
case SYS_SOCKET:
return wasm_socket(a, b, c);
case SYS_CONNECT:
return wasm_connect(a, b, c);
case SYS_ACCEPT:
return wasm_accept(a, b, c);
case SYS_BIND:
return wasm_bind(a, b, c);
case SYS_LISTEN:
return wasm_listen(a, b);
case SYS_SENDTO:
return wasm_sendto(a, b, c, d, e, f);
case SYS_RECVFROM:
return wasm_recvfrom(a, b, c, d, e, f);
}
printf("syscall %d (%d, %d, %d, %d, %d, %d)\n", n, a, b, c, d, e, f);
assert(0);

File diff suppressed because it is too large Load Diff

@ -23,12 +23,11 @@ pthread_t rtthd[SBOX_NCORES];
static unsigned long long
get_time()
{
struct timeval Tp;
int stat;
stat = gettimeofday (&Tp, NULL);
if (stat != 0)
printf ("Error return from gettimeofday: %d", stat);
return (Tp.tv_sec * 1000000 + Tp.tv_usec);
struct timeval Tp;
int stat;
stat = gettimeofday(&Tp, NULL);
if (stat != 0) printf("Error return from gettimeofday: %d", stat);
return (Tp.tv_sec * 1000000 + Tp.tv_usec);
}
@ -40,11 +39,11 @@ usage(char *cmd)
}
int
main(int argc, char** argv)
main(int argc, char **argv)
{
#ifndef STANDALONE
int i = 0, rtthd_ret[SBOX_NCORES] = { 0 };
memset(rtthd, 0, sizeof(pthread_t)*SBOX_NCORES);
memset(rtthd, 0, sizeof(pthread_t) * SBOX_NCORES);
if (argc != 2) {
usage(argv[0]);
@ -73,14 +72,15 @@ main(int argc, char** argv)
ncores = sysconf(_SC_NPROCESSORS_ONLN);
if (ncores > 1) {
u32 x = ncores - 1;
u32 x = ncores - 1;
sbox_ncores = SBOX_NCORES;
if (x < SBOX_NCORES) sbox_ncores = x;
sbox_core_st = 1;
} else {
sbox_ncores = 1;
}
debuglog("Number of cores %u, sandboxing cores %u (start: %u) and module reqs %u\n", ncores, sbox_ncores, sbox_core_st, MOD_REQ_CORE);
debuglog("Number of cores %u, sandboxing cores %u (start: %u) and module reqs %u\n", ncores, sbox_ncores,
sbox_core_st, MOD_REQ_CORE);
#ifdef NOSTDIO
fclose(stdout);
@ -119,7 +119,7 @@ main(int argc, char** argv)
assert(ret == 0);
}
debuglog("Sandboxing environment ready!\n");
for (i = 0; i < sbox_ncores; i++) {
int ret = pthread_join(rtthd[i], NULL);
if (ret) {
@ -136,12 +136,12 @@ main(int argc, char** argv)
arch_context_init(&base_context, 0, 0);
uv_loop_init(&uvio);
int ac = 1;
int ac = 1;
char *args = argv[1];
if (argc - 1 > 1) {
ac = argc - 1;
ac = argc - 1;
char **av = argv + 1;
args = malloc(sizeof(char) * MOD_ARG_MAX_SZ * ac);
args = malloc(sizeof(char) * MOD_ARG_MAX_SZ * ac);
memset(args, 0, sizeof(char) * MOD_ARG_MAX_SZ * ac);
for (int i = 0; i < ac; i++) {
@ -154,10 +154,10 @@ main(int argc, char** argv)
struct module *m = module_alloc(args, args, ac, 0, 0, 0, 0, 0, 0);
assert(m);
//unsigned long long st = get_time(), en;
// unsigned long long st = get_time(), en;
struct sandbox *s = sandbox_alloc(m, args, 0, NULL);
//en = get_time();
//fprintf(stderr, "%llu\n", en - st);
// en = get_time();
// fprintf(stderr, "%llu\n", en - st);
exit(0);
#endif

@ -31,7 +31,8 @@ expand_memory(void)
char *mem_as_chars = sandbox_lmbase;
char *page_address = &mem_as_chars[sandbox_lmbound];
void *map_result = mmap(page_address, WASM_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
void *map_result = mmap(page_address, WASM_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (map_result == MAP_FAILED) {
perror("Mapping of new memory failed");
exit(1);
@ -45,13 +46,13 @@ expand_memory(void)
INLINE char *
get_memory_ptr_for_runtime(u32 offset, u32 bounds_check)
{
// Due to how we setup memory for x86, the virtual memory mechanism will catch the error, if bounds < WASM_PAGE_SIZE
assert(bounds_check < WASM_PAGE_SIZE ||
(sandbox_lmbound > bounds_check &&
offset <= sandbox_lmbound - bounds_check));
// Due to how we setup memory for x86, the virtual memory mechanism will catch the error, if bounds <
// WASM_PAGE_SIZE
assert(bounds_check < WASM_PAGE_SIZE
|| (sandbox_lmbound > bounds_check && offset <= sandbox_lmbound - bounds_check));
char *mem_as_chars = (char *)sandbox_lmbase;
char *address = &mem_as_chars[offset];
char *address = &mem_as_chars[offset];
return address;
}

@ -1,12 +1,12 @@
#include <runtime.h>
__thread struct indirect_table_entry *module_indirect_table = NULL;
__thread void *sandbox_lmbase = NULL;
__thread u32 sandbox_lmbound = 0;
__thread void * sandbox_lmbase = NULL;
__thread u32 sandbox_lmbound = 0;
// Region initialization helper function
EXPORT void
initialize_region(u32 offset, u32 data_count, char* data)
initialize_region(u32 offset, u32 data_count, char *data)
{
assert(sandbox_lmbound >= data_count);
assert(offset < sandbox_lmbound - data_count);
@ -16,14 +16,14 @@ initialize_region(u32 offset, u32 data_count, char* data)
}
void
add_function_to_table(u32 idx, u32 type_id, char* pointer)
add_function_to_table(u32 idx, u32 type_id, char *pointer)
{
assert(idx < INDIRECT_TABLE_SIZE);
// TODO: atomic for multiple concurrent invocations?
if (module_indirect_table[idx].type_id == type_id && module_indirect_table[idx].func_pointer == pointer) return;
module_indirect_table[idx] = (struct indirect_table_entry) { .type_id = type_id, .func_pointer = pointer };
module_indirect_table[idx] = (struct indirect_table_entry){ .type_id = type_id, .func_pointer = pointer };
}
// If we are using runtime globals, we need to populate them
@ -32,4 +32,3 @@ populate_globals()
{
assert(0); // FIXME: is this used in WASM as dynamic modules?
}

@ -7,7 +7,7 @@
#include <util.h>
static struct module *__mod_db[MOD_MAX] = { NULL };
static int __mod_free_off = 0;
static int __mod_free_off = 0;
struct module *
module_find_by_name(char *name)
@ -55,9 +55,9 @@ module_server_init(struct module *m)
#ifndef STANDALONE
int fd = socket(AF_INET, SOCK_STREAM, 0);
assert(fd > 0);
m->srvaddr.sin_family = AF_INET;
m->srvaddr.sin_family = AF_INET;
m->srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
m->srvaddr.sin_port = htons((unsigned short)m->srvport);
m->srvaddr.sin_port = htons((unsigned short)m->srvport);
int optval = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
@ -79,7 +79,8 @@ module_server_init(struct module *m)
}
struct module *
module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap, u32 timeout, int port, int req_sz, int resp_sz)
module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap, u32 timeout, int port, int req_sz,
int resp_sz)
{
struct module *mod = (struct module *)malloc(sizeof(struct module));
if (!mod) return NULL;
@ -90,7 +91,7 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap,
mod->entry_fn = (mod_main_fn_t)dlsym(mod->dl_handle, MOD_MAIN_FN);
if (mod->entry_fn == NULL) goto dl_error;
mod->glb_init_fn = (mod_glb_fn_t)dlsym(mod->dl_handle, MOD_GLB_FN);
if (mod->glb_init_fn == NULL) goto dl_error;
@ -106,7 +107,7 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap,
strncpy(mod->name, modname, MOD_NAME_MAX);
strncpy(mod->path, modpath, MOD_PATH_MAX);
mod->nargs = nargs;
mod->nargs = nargs;
mod->stack_size = round_up_to_page(stacksz == 0 ? WASM_STACK_SIZE : stacksz);
mod->max_memory = maxheap == 0 ? ((u64)WASM_PAGE_SIZE * WASM_MAX_PAGES) : maxheap;
mod->timeout = timeout;
@ -115,9 +116,9 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap,
mod->srvport = port;
if (req_sz == 0) req_sz = MOD_REQ_RESP_DEFAULT;
if (resp_sz == 0) resp_sz = MOD_REQ_RESP_DEFAULT;
mod->max_req_sz = req_sz;
mod->max_req_sz = req_sz;
mod->max_resp_sz = resp_sz;
mod->max_rr_sz = round_up_to_page(req_sz > resp_sz ? req_sz : resp_sz);
mod->max_rr_sz = round_up_to_page(req_sz > resp_sz ? req_sz : resp_sz);
#endif
struct indirect_table_entry *cache_tbl = module_indirect_table;

@ -12,8 +12,8 @@
#include <http_api.h>
struct deque_sandbox *glb_dq;
pthread_mutex_t glbq_mtx = PTHREAD_MUTEX_INITIALIZER;
int epfd;
pthread_mutex_t glbq_mtx = PTHREAD_MUTEX_INITIALIZER;
int epfd;
// per-thread (per-core) run and completion queue.. (using doubly-linked-lists)
__thread static struct ps_list_head runq;
@ -35,7 +35,7 @@ static inline void
sandbox_local_run(struct sandbox *s)
{
assert(ps_list_singleton_d(s));
// fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, s->mod->name);
// fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, s->mod->name);
ps_list_head_append_d(&runq, s);
}
@ -95,7 +95,7 @@ sandbox_schedule(int interrupt)
// this is in an interrupt context, don't steal work here!
if (interrupt) return NULL;
if (sandbox_pull() == 0) {
//debuglog("[null: null]\n");
// debuglog("[null: null]\n");
return NULL;
}
}
@ -164,9 +164,9 @@ sandbox_block(void)
softint_disable();
struct sandbox *c = sandbox_current();
ps_list_rem_d(c);
c->state = SANDBOX_BLOCKED;
c->state = SANDBOX_BLOCKED;
struct sandbox *s = sandbox_schedule(0);
debuglog("[%p: %s, %p: %s]\n", c, c->mod->name, s, s ? s->mod->name: "");
debuglog("[%p: %s, %p: %s]\n", c, c->mod->name, s, s ? s->mod->name : "");
softint_enable();
sandbox_switch(s);
#else
@ -179,26 +179,26 @@ sandbox_block_http(void)
{
#ifdef USE_HTTP_UVIO
#ifdef USE_HTTP_SYNC
// realistically, we're processing all async I/O on this core when a sandbox blocks on http processing, not great!
// if there is a way (TODO), perhaps RUN_ONCE and check if your I/O is processed, if yes, return
// else do async block!
// realistically, we're processing all async I/O on this core when a sandbox blocks on http processing, not
// great! if there is a way (TODO), perhaps RUN_ONCE and check if your I/O is processed, if yes, return else do
// async block!
uv_run(runtime_uvio(), UV_RUN_DEFAULT);
#else
sandbox_block();
#endif
#else
assert(0);
//it should not be called if not using uvio for http
// it should not be called if not using uvio for http
#endif
}
void __attribute__((noinline)) __attribute__((noreturn))
sandbox_switch_preempt(void)
void __attribute__((noinline)) __attribute__((noreturn)) sandbox_switch_preempt(void)
{
pthread_kill(pthread_self(), SIGUSR1);
assert(0); // should not get here..
while (1) ;
while (1)
;
}
static inline void
sandbox_local_stop(struct sandbox *s)
@ -220,13 +220,13 @@ sandbox_run_func(void *data)
ps_list_head_init(&runq);
ps_list_head_init(&endq);
softint_off = 0;
softint_off = 0;
next_context = NULL;
#ifndef PREEMPT_DISABLE
softint_unmask(SIGALRM);
softint_unmask(SIGUSR1);
#endif
uv_loop_init(&uvio);
uv_loop_init(&uvio);
in_callback = 0;
while (1) {
@ -245,7 +245,7 @@ void
sandbox_run(sbox_request_t *s)
{
#ifndef STANDALONE
// for now, a pull model...
// for now, a pull model...
// sandbox_run adds to the global ready queue..
// each sandboxing thread pulls off of that global ready queue..
debuglog("[%p: %s]\n", s, s->mod->name);
@ -268,13 +268,13 @@ sandbox_exit(void)
softint_disable();
sandbox_local_stop(curr);
curr->state = SANDBOX_RETURNED;
// free resources from "main function execution", as stack still in use.
// free resources from "main function execution", as stack still in use.
struct sandbox *n = sandbox_schedule(0);
assert(n != curr);
softint_enable();
//unmap linear memory only!
// unmap linear memory only!
munmap(curr->linear_start, SBOX_MAX_MEM + PAGE_SIZE);
//sandbox_local_end(curr);
// sandbox_local_end(curr);
sandbox_switch(n);
#else
sandbox_switch(NULL);
@ -286,7 +286,7 @@ runtime_accept_thdfn(void *d)
{
#ifndef STANDALONE
struct epoll_event *epevts = (struct epoll_event *)malloc(EPOLL_MAX * sizeof(struct epoll_event));
int nreqs = 0;
int nreqs = 0;
while (1) {
int ready = epoll_wait(epfd, epevts, EPOLL_MAX, -1);
for (int i = 0; i < ready; i++) {
@ -296,18 +296,18 @@ runtime_accept_thdfn(void *d)
}
struct sockaddr_in client;
socklen_t client_len = sizeof(client);
struct module *m = (struct module *)epevts[i].data.ptr;
socklen_t client_len = sizeof(client);
struct module * m = (struct module *)epevts[i].data.ptr;
assert(m);
int es = m->srvsock;
int s = accept(es, (struct sockaddr *)&client, &client_len);
int s = accept(es, (struct sockaddr *)&client, &client_len);
if (s < 0) {
perror("accept");
assert(0);
}
nreqs++;
//struct sandbox *sb = sandbox_alloc(m, m->name, s, (const struct sockaddr *)&client);
// struct sandbox *sb = sandbox_alloc(m, m->name, s, (const struct sockaddr *)&client);
sbox_request_t *sb = sbox_request_alloc(m, m->name, s, (const struct sockaddr *)&client);
assert(sb);
}
@ -324,9 +324,9 @@ runtime_init(void)
{
epfd = epoll_create1(0);
assert(epfd >= 0);
glb_dq = (struct deque_sandbox *)malloc(sizeof(struct deque_sandbox));
glb_dq = (struct deque_sandbox *)malloc(sizeof(struct deque_sandbox));
assert(glb_dq);
deque_init_sandbox(glb_dq, SBOX_MAX_REQS);
deque_init_sandbox(glb_dq, SBOX_MAX_REQS);
softint_mask(SIGUSR1);
softint_mask(SIGALRM);
@ -343,7 +343,7 @@ runtime_thd_init(void)
CPU_SET(MOD_REQ_CORE, &cs);
pthread_t iothd;
int ret = pthread_create(&iothd, NULL, runtime_accept_thdfn, NULL);
int ret = pthread_create(&iothd, NULL, runtime_accept_thdfn, NULL);
assert(ret == 0);
ret = pthread_setaffinity_np(iothd, sizeof(cpu_set_t), &cs);
assert(ret == 0);

@ -20,11 +20,13 @@ sandbox_memory_map(struct module *m)
if (lm_sz + sb_sz > mem_sz) return NULL;
assert(round_up_to_page(sb_sz) == sb_sz);
unsigned long rw_sz = sb_sz + lm_sz;
void *addr = mmap(NULL, sb_sz + mem_sz + /* guard page */ PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
unsigned long rw_sz = sb_sz + lm_sz;
void *addr = mmap(NULL, sb_sz + mem_sz + /* guard page */ PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1,
0);
if (addr == MAP_FAILED) return NULL;
void *addr_rw = mmap(addr, sb_sz + lm_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
void *addr_rw = mmap(addr, sb_sz + lm_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1,
0);
if (addr_rw == MAP_FAILED) {
munmap(addr, mem_sz + PAGE_SIZE);
return NULL;
@ -33,9 +35,9 @@ sandbox_memory_map(struct module *m)
struct sandbox *s = (struct sandbox *)addr;
// can it include sandbox as well?
s->linear_start = (char *)addr + sb_sz;
s->linear_size = lm_sz;
s->mod = m;
s->sb_size = sb_sz;
s->linear_size = lm_sz;
s->mod = m;
s->sb_size = sb_sz;
module_acquire(m);
return s;
@ -45,18 +47,18 @@ static inline void
sandbox_args_setup(i32 argc)
{
struct sandbox *curr = sandbox_current();
char *args = sandbox_args();
char * args = sandbox_args();
// whatever gregor has, to be able to pass args to a module!
curr->args_offset = sandbox_lmbound;
assert(sandbox_lmbase == curr->linear_start);
expand_memory();
i32 *array_ptr = get_memory_ptr_void(curr->args_offset, argc * sizeof(i32));
i32 string_off = curr->args_offset + (argc * sizeof(i32));
i32 *array_ptr = get_memory_ptr_void(curr->args_offset, argc * sizeof(i32));
i32 string_off = curr->args_offset + (argc * sizeof(i32));
for (int i = 0; i < argc; i++) {
char *arg = args + (i * MOD_ARG_MAX_SZ);
char * arg = args + (i * MOD_ARG_MAX_SZ);
size_t str_sz = strlen(arg) + 1;
array_ptr[i] = string_off;
@ -77,7 +79,7 @@ sb_read_callback(uv_stream_t *s, ssize_t nr, const uv_buf_t *b)
if (nr > 0) {
if (http_request_parse_sb(c, nr) != 0) return;
c->rr_data_len += nr;
struct http_request *rh = &c->rqi;
struct http_request *rh = &c->rqi;
if (!rh->message_end) return;
}
@ -120,9 +122,9 @@ sb_alloc_callback(uv_handle_t *h, size_t suggested, uv_buf_t *buf)
struct sandbox *c = h->data;
#ifndef STANDALONE
size_t l = (c->mod->max_rr_sz - c->rr_data_len);
size_t l = (c->mod->max_rr_sz - c->rr_data_len);
buf->base = (c->req_resp_data + c->rr_data_len);
buf->len = l > suggested ? suggested : l;
buf->len = l > suggested ? suggested : l;
#endif
}
@ -135,7 +137,7 @@ sandbox_client_request_get(void)
curr->rr_data_len = 0;
#ifndef USE_HTTP_UVIO
int r = 0;
r = recv(curr->csock, (curr->req_resp_data), curr->mod->max_req_sz, 0);
r = recv(curr->csock, (curr->req_resp_data), curr->mod->max_req_sz, 0);
if (r <= 0) {
if (r < 0) perror("recv1");
return r;
@ -146,7 +148,8 @@ sandbox_client_request_get(void)
struct http_request *rh = &curr->rqi;
if (rh->message_end) break;
r = recv(curr->csock, (curr->req_resp_data + curr->rr_data_len), curr->mod->max_req_sz - curr->rr_data_len, 0);
r = recv(curr->csock, (curr->req_resp_data + curr->rr_data_len),
curr->mod->max_req_sz - curr->rr_data_len, 0);
if (r < 0) {
perror("recv2");
return r;
@ -168,21 +171,24 @@ static inline int
sandbox_client_response_set(void)
{
#ifndef STANDALONE
int sndsz = 0;
struct sandbox *curr = sandbox_current();
int rsp_hdr_len = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN);
int bodylen = curr->rr_data_len - rsp_hdr_len;
int sndsz = 0;
struct sandbox *curr = sandbox_current();
int rsp_hdr_len = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN);
int bodylen = curr->rr_data_len - rsp_hdr_len;
memset(curr->req_resp_data, 0, strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN));
memset(curr->req_resp_data, 0,
strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN));
strncpy(curr->req_resp_data, HTTP_RESP_200OK, strlen(HTTP_RESP_200OK));
sndsz += strlen(HTTP_RESP_200OK);
if (bodylen == 0) goto done;
strncpy(curr->req_resp_data + sndsz, HTTP_RESP_CONTTYPE, strlen(HTTP_RESP_CONTTYPE));
if (strlen(curr->mod->rspctype) <= 0) {
strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), HTTP_RESP_CONTTYPE_PLAIN, strlen(HTTP_RESP_CONTTYPE_PLAIN));
strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), HTTP_RESP_CONTTYPE_PLAIN,
strlen(HTTP_RESP_CONTTYPE_PLAIN));
} else {
strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), curr->mod->rspctype, strlen(curr->mod->rspctype));
strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), curr->mod->rspctype,
strlen(curr->mod->rspctype));
}
sndsz += strlen(HTTP_RESP_CONTTYPE);
char len[10] = { 0 };
@ -210,9 +216,11 @@ done:
r += s;
}
#else
uv_write_t req = { .data = curr, };
uv_write_t req = {
.data = curr,
};
uv_buf_t bufv = uv_buf_init(curr->req_resp_data, sndsz);
int r = uv_write(&req, (uv_stream_t *)&curr->cuv, &bufv, 1, sb_write_callback);
int r = uv_write(&req, (uv_stream_t *)&curr->cuv, &bufv, 1, sb_write_callback);
sandbox_block_http();
#endif
@ -221,8 +229,8 @@ done:
#endif
}
//static inline int
//sandbox_client_response_set(void)
// static inline int
// sandbox_client_response_set(void)
//{
//#ifndef STANDALONE
// struct sandbox *curr = sandbox_current();
@ -285,7 +293,7 @@ sandbox_entry(void)
{
struct sandbox *curr = sandbox_current();
// FIXME: is this right? this is the first time this sandbox is running.. so it wont
// return to sandbox_switch() api..
// return to sandbox_switch() api..
// we'd potentially do what we'd in sandbox_switch() api here for cleanup..
if (!softint_enabled()) {
arch_context_init(&curr->ctxt, 0, 0);
@ -293,7 +301,7 @@ sandbox_entry(void)
softint_enable();
}
struct module *curr_mod = sandbox_module(curr);
int argc = module_nargs(curr_mod);
int argc = module_nargs(curr_mod);
// for stdio
int f = io_handle_open(0);
assert(f == 0);
@ -315,7 +323,7 @@ sandbox_entry(void)
int r = uv_tcp_init(runtime_uvio(), (uv_tcp_t *)&curr->cuv);
assert(r == 0);
curr->cuv.data = curr;
r = uv_tcp_open((uv_tcp_t *)&curr->cuv, curr->csock);
r = uv_tcp_open((uv_tcp_t *)&curr->cuv, curr->csock);
assert(r == 0);
#endif
if (sandbox_client_request_get() > 0)
@ -328,7 +336,7 @@ sandbox_entry(void)
#endif
alloc_linear_memory();
// perhaps only initialized for the first instance? or TODO!
//module_table_init(curr_mod);
// module_table_init(curr_mod);
module_globals_init(curr_mod);
module_memory_init(curr_mod);
sandbox_args_setup(argc);
@ -359,10 +367,11 @@ sandbox_alloc(struct module *mod, char *args, int sock, const struct sockaddr *a
struct sandbox *sb = (struct sandbox *)sandbox_memory_map(mod);
if (!sb) return NULL;
//actual module instantiation!
sb->args = (void *)args;
sb->stack_size = mod->stack_size;
sb->stack_start = mmap(NULL, sb->stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
// actual module instantiation!
sb->args = (void *)args;
sb->stack_size = mod->stack_size;
sb->stack_start = mmap(NULL, sb->stack_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
if (sb->stack_start == MAP_FAILED) {
perror("mmap");
assert(0);
@ -405,19 +414,19 @@ sandbox_free(struct sandbox *sb)
module_release(sb->mod);
// TODO free(sb->args);
void *stkaddr = sb->stack_start;
size_t stksz = sb->stack_size;
void * stkaddr = sb->stack_start;
size_t stksz = sb->stack_size;
// depending on the memory type
//free_linear_memory(sb->linear_start, sb->linear_size, sb->linear_max_size);
// free_linear_memory(sb->linear_start, sb->linear_size, sb->linear_max_size);
// mmaped memory includes sandbox structure in there.
ret = munmap(sb, sz);
if (ret) perror("munmap sandbox");
// remove stack!
// for some reason, removing stack seem to cause crash in some cases.
// TODO: debug more.
// for some reason, removing stack seem to cause crash in some cases.
// TODO: debug more.
ret = munmap(stkaddr, stksz);
if (ret) perror("munmap stack");
}

@ -17,10 +17,7 @@ __thread static volatile sig_atomic_t alarm_cnt = 0, usr1_cnt = 0;
__thread volatile sig_atomic_t softint_off = 0;
static const int softints[] = {
SIGALRM,
SIGUSR1
};
static const int softints[] = { SIGALRM, SIGUSR1 };
void
softint_timer_arm(void)
@ -29,7 +26,7 @@ softint_timer_arm(void)
struct itimerval it;
memset(&it, 0, sizeof(struct itimerval));
it.it_value.tv_usec = SOFTINT_TIMER_START_USEC;
it.it_value.tv_usec = SOFTINT_TIMER_START_USEC;
it.it_interval.tv_usec = SOFTINT_TIMER_PERIOD_USEC;
int ret = setitimer(ITIMER_REAL, &it, NULL);
@ -46,7 +43,7 @@ softint_timer_disarm(void)
struct itimerval it;
memset(&it, 0, sizeof(struct itimerval));
it.it_value.tv_sec = 0;
it.it_value.tv_sec = 0;
it.it_interval.tv_usec = 0;
int ret = setitimer(ITIMER_REAL, &it, NULL);
@ -59,13 +56,13 @@ softint_timer_disarm(void)
static inline void
softint_alarm_schedule(void *u)
{
softint_disable(); //no nesting!
softint_disable(); // no nesting!
struct sandbox *curr = sandbox_current();
ucontext_t *uc = (ucontext_t *)u;
ucontext_t * uc = (ucontext_t *)u;
// no sandboxes running..so nothing to preempt..let the "main" scheduler run its course.
if (curr == NULL) goto done;
// find a next sandbox to run..
struct sandbox *next = sandbox_schedule(1);
if (next == NULL) goto done;
@ -77,8 +74,8 @@ softint_alarm_schedule(void *u)
sandbox_current_set(next);
if (arch_mcontext_restore(&uc->uc_mcontext, &next->ctxt)) goto skip;
// reset if SIGALRM happens before SIGUSR1 and if don't preempt..OR
// perhaps switch here for SIGUSR1 and see if we can clear that signal
// reset if SIGALRM happens before SIGUSR1 and if don't preempt..OR
// perhaps switch here for SIGUSR1 and see if we can clear that signal
// so it doesn't get called on SIGALRM return..
// next_context = NULL;
@ -97,15 +94,14 @@ softint_handler(int sig, siginfo_t *si, void *u)
assert(0);
#else
struct sandbox *curr = sandbox_current();
ucontext_t *uc = (ucontext_t *)u;
ucontext_t * uc = (ucontext_t *)u;
switch(sig) {
case SIGALRM:
{
switch (sig) {
case SIGALRM: {
// if interrupts are disabled.. increment a per_thread counter and return
if (si->si_code == SI_KERNEL) {
int rt = 0;
// deliver signal to all other runtime threads..
// deliver signal to all other runtime threads..
for (int i = 0; i < SBOX_NCORES; i++) {
if (pthread_self() == rtthd[i]) {
rt = 1;
@ -117,25 +113,24 @@ softint_handler(int sig, siginfo_t *si, void *u)
} else {
assert(si->si_code == SI_TKILL);
}
//debuglog("alrm:%d\n", alarm_cnt);
// debuglog("alrm:%d\n", alarm_cnt);
alarm_cnt++;
// softints per-core..
if (curr && curr->state == SANDBOX_RETURNED) return;
if (next_context) return;
if (!softint_enabled()) return;
if (!softint_enabled()) return;
softint_alarm_schedule(u);
break;
}
case SIGUSR1:
{
case SIGUSR1: {
// make sure sigalrm doesn't mess this up if nested..
assert(!softint_enabled());
/* we set current before calling pthread_kill! */
assert(next_context && (&curr->ctxt == next_context));
assert(si->si_code == SI_TKILL);
//debuglog("usr1:%d\n", usr1_cnt);
// debuglog("usr1:%d\n", usr1_cnt);
usr1_cnt++;
// do not save current sandbox.. it is in co-operative switch..
@ -150,15 +145,16 @@ softint_handler(int sig, siginfo_t *si, void *u)
case SIGPIPE:
case SIGILL:
case SIGFPE:
case SIGSEGV:
{
// determine if the crash was in the sandbox..
case SIGSEGV: {
// determine if the crash was in the sandbox..
// if (pthread_self() == one_of_the_runtime_threads), a sandbox crashed.. kill it.
// another check there could be if it is in linear memory or outside, if outside it could repeat with other sandboxes.. so perhaps restart that thread or start a fresh thread??.
// else, shoot yourself in the head!..
// another check there could be if it is in linear memory or outside, if outside it could repeat with
// other sandboxes.. so perhaps restart that thread or start a fresh thread??. else, shoot yourself in
// the head!..
break;
}
default: break;
default:
break;
}
#endif
}
@ -169,7 +165,7 @@ softint_init(void)
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_sigaction = softint_handler;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
for (int i = 0; i < (sizeof(softints) / sizeof(softints[0])); i++) {
int ret = sigaction(softints[i], &sa, NULL);

@ -17,7 +17,7 @@ util_remove_spaces(char *str)
int i = 0;
while (isspace(*str)) str++;
i = strlen(str);
while (isspace(str[i-1])) str[i-1]='\0';
while (isspace(str[i - 1])) str[i - 1] = '\0';
return str;
}
@ -63,29 +63,30 @@ util_parse_modules_file_json(char *filename)
for (int i = 0; i < r; i++) {
assert(toks[i].type == JSMN_OBJECT);
char mname[MOD_NAME_MAX] = { 0 };
char mpath[MOD_PATH_MAX] = { 0 };
char mname[MOD_NAME_MAX] = { 0 };
char mpath[MOD_PATH_MAX] = { 0 };
char *rqhdrs;
char *rsphdrs;
i32 req_sz = 0;
i32 resp_sz = 0;
i32 nargs = 0;
u32 port = 0;
i32 isactive = 0;
i32 nreqs = 0, nresps = 0;
int j = 1, ntoks = 2 * toks[i].size;
i32 req_sz = 0;
i32 resp_sz = 0;
i32 nargs = 0;
u32 port = 0;
i32 isactive = 0;
i32 nreqs = 0, nresps = 0;
int j = 1, ntoks = 2 * toks[i].size;
rqhdrs = (char *)malloc(HTTP_HEADER_MAXSZ * HTTP_HEADERS_MAX);
memset(rqhdrs, 0, HTTP_HEADER_MAXSZ * HTTP_HEADERS_MAX);
rsphdrs = (char *)malloc(HTTP_HEADER_MAXSZ * HTTP_HEADERS_MAX);
memset(rsphdrs, 0, HTTP_HEADER_MAXSZ * HTTP_HEADERS_MAX);
char rqtype[HTTP_HEADERVAL_MAXSZ] = { 0 };
char rqtype[HTTP_HEADERVAL_MAXSZ] = { 0 };
char rsptype[HTTP_HEADERVAL_MAXSZ] = { 0 };
for (; j < ntoks; ) {
int ntks = 1;
for (; j < ntoks;) {
int ntks = 1;
char val[256] = { 0 }, key[32] = { 0 };
sprintf(val, "%.*s", toks[j + i + 1].end - toks[j + i + 1].start, filebuf + toks[j + i + 1].start);
sprintf(val, "%.*s", toks[j + i + 1].end - toks[j + i + 1].start,
filebuf + toks[j + i + 1].start);
sprintf(key, "%.*s", toks[j + i].end - toks[j + i].start, filebuf + toks[j + i].start);
if (strcmp(key, "name") == 0) {
strcpy(mname, val);
@ -107,9 +108,9 @@ util_parse_modules_file_json(char *filename)
ntoks += nreqs;
for (int k = 1; k <= toks[i + j + 1].size; k++) {
jsmntok_t *g = &toks[i + j + k + 1];
char *r = rqhdrs + ((k-1)*HTTP_HEADER_MAXSZ);
char * r = rqhdrs + ((k - 1) * HTTP_HEADER_MAXSZ);
assert(g->end - g->start < HTTP_HEADER_MAXSZ);
strncpy(r, filebuf + g->start, g->end - g->start);
strncpy(r, filebuf + g->start, g->end - g->start);
}
} else if (strcmp(key, "http-resp-headers") == 0) {
assert(toks[i + j + 1].type == JSMN_ARRAY);
@ -119,10 +120,10 @@ util_parse_modules_file_json(char *filename)
nresps = toks[i + j + 1].size;
ntks += nresps;
for (int k = 1; k <= toks[i + j + 1].size; k++) {
char *r = rsphdrs + ((k-1)*HTTP_HEADER_MAXSZ);
char * r = rsphdrs + ((k - 1) * HTTP_HEADER_MAXSZ);
jsmntok_t *g = &toks[i + j + k + 1];
assert(g->end - g->start < HTTP_HEADER_MAXSZ);
strncpy(r, filebuf + g->start, g->end - g->start);
strncpy(r, filebuf + g->start, g->end - g->start);
}
ntoks += nresps;
} else if (strcmp(key, "http-req-size") == 0) {
@ -136,7 +137,7 @@ util_parse_modules_file_json(char *filename)
} else {
debuglog("Invalid (%s,%s)\n", key, val);
}
j += ntks;
j += ntks;
}
i += ntoks;
// do not load if it is not active
@ -166,9 +167,9 @@ util_parse_modules_file_json(char *filename)
int
parse_sandbox_file_custom(char *filename)
{
FILE *mf = fopen(filename, "r");
char buff[UTIL_MOD_LINE_MAX] = { 0 };
int total_boxes = 0;
FILE *mf = fopen(filename, "r");
char buff[UTIL_MOD_LINE_MAX] = { 0 };
int total_boxes = 0;
if (!mf) {
perror("fopen");
@ -177,11 +178,11 @@ parse_sandbox_file_custom(char *filename)
}
while (fgets(buff, UTIL_MOD_LINE_MAX, mf) != NULL) {
char mname[MOD_NAME_MAX] = { 0 };
char *tok = NULL, *src = buff;
struct module *mod = NULL;
struct sandbox *sb = NULL;
char *args = NULL;
char mname[MOD_NAME_MAX] = { 0 };
char * tok = NULL, *src = buff;
struct module * mod = NULL;
struct sandbox *sb = NULL;
char * args = NULL;
src = util_remove_spaces(src);
if (src[0] == ';') goto next;
@ -211,7 +212,7 @@ parse_sandbox_file_custom(char *filename)
assert(sb);
total_boxes++;
next:
next:
memset(buff, 0, UTIL_MOD_LINE_MAX);
}
@ -226,10 +227,10 @@ struct sandbox *
util_parse_sandbox_string_json(struct module *mod, char *str, const struct sockaddr *addr)
{
jsmn_parser sp;
jsmntok_t tk[JSON_ELE_MAX];
jsmntok_t tk[JSON_ELE_MAX];
jsmn_init(&sp);
int r = jsmn_parse(&sp, str, strlen(str), tk, sizeof(tk)/sizeof(tk[0]));
int r = jsmn_parse(&sp, str, strlen(str), tk, sizeof(tk) / sizeof(tk[0]));
if (r < 1) {
debuglog("Failed to parse string:%s\n", str);
return NULL;
@ -294,7 +295,7 @@ util_parse_sandbox_string_custom(struct module *mod, char *str, const struct soc
struct sandbox *sb = sandbox_alloc(mod, args, 0, addr);
assert(sb);
return sb;
return sb;
}
/*
@ -306,9 +307,9 @@ util_parse_sandbox_string_custom(struct module *mod, char *str, const struct soc
int
util_parse_modules_file_custom(char *filename)
{
FILE *mf = fopen(filename, "r");
char buff[UTIL_MOD_LINE_MAX] = { 0 };
int nmods = 0;
FILE *mf = fopen(filename, "r");
char buff[UTIL_MOD_LINE_MAX] = { 0 };
int nmods = 0;
if (!mf) {
perror("fopen");
@ -317,25 +318,33 @@ util_parse_modules_file_custom(char *filename)
}
while (fgets(buff, UTIL_MOD_LINE_MAX, mf) != NULL) {
char mname[MOD_NAME_MAX] = { 0 };
char mpath[MOD_PATH_MAX] = { 0 };
i32 nargs = 0;
u32 stack_sz = 0;
u32 max_heap = 0;
u32 timeout = 0;
char mname[MOD_NAME_MAX] = { 0 };
char mpath[MOD_PATH_MAX] = { 0 };
i32 nargs = 0;
u32 stack_sz = 0;
u32 max_heap = 0;
u32 timeout = 0;
char *tok = NULL, *src = buff;
u32 port = 0;
i32 ntoks = 0;
u32 port = 0;
i32 ntoks = 0;
src = util_remove_spaces(src);
if (src[0] == ';') goto next;
while ((tok = strtok_r(src, ":", &src))) {
switch(ntoks) {
case MOD_ARG_MODPATH: strncpy(mpath, tok, MOD_PATH_MAX); break;
case MOD_ARG_MODPORT: port = atoi(tok);
case MOD_ARG_MODNAME: strncpy(mname, tok, MOD_NAME_MAX); break;
case MOD_ARG_MODNARGS: nargs = atoi(tok); break;
default: break;
switch (ntoks) {
case MOD_ARG_MODPATH:
strncpy(mpath, tok, MOD_PATH_MAX);
break;
case MOD_ARG_MODPORT:
port = atoi(tok);
case MOD_ARG_MODNAME:
strncpy(mname, tok, MOD_NAME_MAX);
break;
case MOD_ARG_MODNARGS:
nargs = atoi(tok);
break;
default:
break;
}
ntoks++;
}
@ -345,7 +354,7 @@ util_parse_modules_file_custom(char *filename)
assert(m);
nmods++;
next:
next:
memset(buff, 0, UTIL_MOD_LINE_MAX);
}
@ -355,4 +364,3 @@ next:
return 0;
}

@ -22,12 +22,11 @@ get_time()
return ret;
#else
struct timeval Tp;
int stat;
stat = gettimeofday (&Tp, NULL);
if (stat != 0)
printf ("Error return from gettimeofday: %d", stat);
return (Tp.tv_sec * 1000000 + Tp.tv_usec);
struct timeval Tp;
int stat;
stat = gettimeofday(&Tp, NULL);
if (stat != 0) printf("Error return from gettimeofday: %d", stat);
return (Tp.tv_sec * 1000000 + Tp.tv_usec);
#endif
}

@ -1,23 +1,22 @@
#include <stdio.h>
#include <stdio.h>
#include "get_time.h"
unsigned long int
fib(unsigned long int n)
{
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
fib(unsigned long int n)
{
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
int
main(int argc, char **argv)
{
main(int argc, char **argv)
{
unsigned long n = 0, r;
scanf("%lu", &n);
// unsigned long long st = get_time(), en;
// unsigned long long st = get_time(), en;
r = fib(n);
// en = get_time();
// en = get_time();
printf("%lu\n", r);
// print_time(st, en);
return 0;
}
// print_time(st, en);
return 0;
}

@ -7,10 +7,11 @@
#include <string.h>
#include <sys/uio.h>
#define BUF_MAX 44
#define BUF_MAX 44
#define RDWR_MAX 1
#if RDWR_MAX > 1
int main(int argc, char **argv) __attribute__ ((optnone))
int
main(int argc, char **argv) __attribute__((optnone))
{
char buf[RDWR_MAX][BUF_MAX] = { 0 };
@ -26,11 +27,11 @@ int main(int argc, char **argv) __attribute__ ((optnone))
return -1;
}
int n = 0;
int n = 0;
struct iovec iov[RDWR_MAX] = { 0 };
for (int i = 0; i < RDWR_MAX; i++) {
iov[i].iov_base = buf[i];
iov[i].iov_len = BUF_MAX;
iov[i].iov_len = BUF_MAX;
}
while ((n = readv(fdr, iov, RDWR_MAX)) > 0) {
int wvcnt = n / BUF_MAX;
@ -43,7 +44,7 @@ int main(int argc, char **argv) __attribute__ ((optnone))
memset(buf, 0, RDWR_MAX * BUF_MAX);
for (int i = 0; i < RDWR_MAX; i++) {
iov[i].iov_base = buf[i];
iov[i].iov_len = BUF_MAX;
iov[i].iov_len = BUF_MAX;
}
n = 0;
}
@ -58,7 +59,7 @@ int main(int argc, char **argv) __attribute__ ((optnone))
#else
int
main(int argc, char **argv) __attribute__ ((optnone))
main(int argc, char **argv) __attribute__((optnone))
{
char buf[BUF_MAX] = { 0 };
@ -100,7 +101,8 @@ main(int argc, char **argv) __attribute__ ((optnone))
while (!feof(fpr)) {
char *p = NULL;
if ((p = fgets(buf, BUF_MAX, fpr)) == NULL) perror("fgets");
if ((p = fgets(buf, BUF_MAX, fpr)) == NULL)
perror("fgets");
else {
if (fputs(p, fpw) < 0) perror("fputs");
p = NULL;

@ -5,7 +5,7 @@
#define ITERS 50000000
int
main(int argc, char **argv) __attribute__ ((optnone))
main(int argc, char **argv) __attribute__((optnone))
{
printf("%s enter\n", argv[0]);
int n = 0, e = 1;
@ -19,7 +19,7 @@ main(int argc, char **argv) __attribute__ ((optnone))
n--;
while (i-- > 0) {
int j = ITERS;
while (j-- > 0) __asm__ __volatile__("nop": : :"memory");
while (j-- > 0) __asm__ __volatile__("nop" : : : "memory");
}
printf("%s\n", argv[0]);
}

@ -3,53 +3,49 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netdb.h>
#include <string.h>
void error(char *msg)
void
error(char *msg)
{
perror(msg);
exit(0);
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
int sockfd, portno, n;
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
struct sockaddr_in serv_addr;
struct hostent * server;
char buffer[256] = "The quick brown fox jumps over the lazy dog";
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Sending message %s\n", buffer);
n = send(sockfd,buffer,strlen(buffer), 0);
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = recv(sockfd,buffer,255, 0);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
char buffer[256] = "The quick brown fox jumps over the lazy dog";
if (argc < 3) {
fprintf(stderr, "usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr, "ERROR, no such host\n");
exit(0);
}
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) error("ERROR connecting");
printf("Sending message %s\n", buffer);
n = send(sockfd, buffer, strlen(buffer), 0);
if (n < 0) error("ERROR writing to socket");
bzero(buffer, 256);
n = recv(sockfd, buffer, 255, 0);
if (n < 0) error("ERROR reading from socket");
printf("%s\n", buffer);
close(sockfd);
return 0;
}

@ -2,50 +2,48 @@
The port number is passed as an argument */
/* code from: http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html */
#include <stdio.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(char *msg)
void
error(char *msg)
{
perror(msg);
exit(1);
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = recv(newsockfd,buffer,255, 0);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = send(newsockfd,"I got your message",18, 0);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr, "ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
bzero((char *)&serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding");
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0) error("ERROR on accept");
bzero(buffer, 256);
n = recv(newsockfd, buffer, 255, 0);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n", buffer);
n = send(newsockfd, "I got your message", 18, 0);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
return 0;
}

@ -3,7 +3,7 @@
#include <string.h>
#ifndef MAX_BUF
#define MAX_BUF (1024*1024*1) //1m
#define MAX_BUF (1024 * 1024 * 1) // 1m
#endif
//__attribute__((optnone)) int
@ -11,16 +11,19 @@ int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)
printf("E\n");
else if (r <= 1)
printf("D\n");
else
write(1, d, r);
return 0;
}

@ -9,16 +9,19 @@ int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)
printf("E\n");
else if (r <= 1)
printf("D\n");
else
write(1, d, r);
return 0;
}

@ -9,16 +9,19 @@ int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)
printf("E\n");
else if (r <= 1)
printf("D\n");
else
write(1, d, r);
return 0;
}

@ -9,16 +9,19 @@ int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)
printf("E\n");
else if (r <= 1)
printf("D\n");
else
write(1, d, r);
return 0;
}

@ -2,23 +2,26 @@
#include <stdio.h>
#include <string.h>
#define MAX_BUF (1024*1024*1) //1m
#define MAX_BUF (1024 * 1024 * 1) // 1m
//__attribute__((optnone)) int
int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0)
printf("E\n");
else if (r <= 1)
printf("D\n");
else
write(1, d, r);
return 0;
}

@ -1,9 +1,9 @@
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
@ -12,8 +12,8 @@
#define SERVER_PORT 10000
#define SERVER_ADDR "127.0.0.1"
#define REQ_MAX 1024
#define POST_MAX (1024*1024)
#define REQ_MAX 1024
#define POST_MAX (1024 * 1024)
#define RESP_MAX 1024
//#define GET_REQUEST "GET %s HTTP/1.0\r\n"
//#define GET_REQUEST "GET %s.ico HTTP/1.1\r\n" \
@ -31,165 +31,144 @@
// "Host: 0.0.0.0=5000\r\n" \
// "Accept: */*\r\n" \
// "\r\n"
#define GET_REQUEST "GET /%s HTTP/1.1\r\n" \
"Host: 0.0.0.0=xxxx\r\n" \
"\r\n"
#define GET_REQUEST \
"GET /%s HTTP/1.1\r\n" \
"Host: 0.0.0.0=xxxx\r\n" \
"\r\n"
#define POST_REQUEST "POST /%s HTTP/1.0\r\n" \
#define POST_REQUEST \
"POST /%s HTTP/1.0\r\n" \
"content-type: image/png\r\n" \
"content-length: %lu\r\n" \
"\r\n"
"content-length: %lu\r\n" \
"\r\n"
#define POST_REQUEST_END "\r\n\r\n"
//Byte array of bitmap of 128 x 128 px:
char img [] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x83, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3, 0xc0, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf, 0xf0, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xfc,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f,
0xfe, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
0xff, 0xff, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc1, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x87, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xe1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff,
0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff,
0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xc7,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc0, 0x3, 0xff, 0xff,
0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0x80, 0x1, 0xff,
0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xfe, 0xf, 0xf0,
0x7f, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xfe, 0x1f,
0xf8, 0x7f, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfc,
0x7f, 0xfe, 0x3f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff,
0xf8, 0x7f, 0xfe, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f,
0xff, 0xf8, 0xff, 0xff, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xf3, 0xff, 0xff, 0xcf, 0xff, 0xf8, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf8, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf8, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff,
0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf8, 0xff, 0xff, 0x1f,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf8, 0x7f, 0xfe,
0x1f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfc, 0x3f,
0xfc, 0x3f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xfe,
0x1f, 0xf8, 0x7f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff,
0xff, 0x7, 0xe0, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f,
0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x8f, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x8f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x9f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xc0, 0xff, 0xff, 0x7, 0xff, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0x80, 0xff, 0xff, 0x3, 0xff, 0xf1, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x80, 0x0, 0x0, 0x1, 0xff, 0xe1, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x18, 0x0, 0x0, 0x10, 0xff, 0xe3,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xfe, 0x18, 0x0, 0x0, 0x18, 0x7f,
0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xfc, 0x3f, 0xff, 0xff, 0xfc,
0x7f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xfc, 0x7f, 0xff, 0xff,
0xfe, 0x3f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf8, 0xff, 0xff,
0xff, 0xfe, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf8, 0xff,
0xff, 0xff, 0xff, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf1,
0xff, 0xe0, 0x3f, 0xff, 0x8f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1,
0xe1, 0xfc, 0x0, 0x1, 0xff, 0x8f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf1, 0xe3, 0xf0, 0x0, 0x0, 0x7f, 0xc7, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf1, 0xc7, 0xf0, 0x3f, 0xe0, 0x3f, 0xc3, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf1, 0xc7, 0xf1, 0xff, 0xfe, 0x3f, 0xe3, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x8f, 0xf1, 0xff, 0xfe, 0x7f, 0xf1, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0xf, 0xf1, 0xff, 0xfc, 0x7f, 0xf1, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xf1, 0xff, 0xfc, 0x7f, 0xf8, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xf9, 0xff, 0xfc, 0x7f, 0xf8, 0x1f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xf8, 0xff, 0xfc, 0x7f, 0xfc, 0x3f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xf8, 0xff, 0xf8, 0xff, 0xfe,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xf8, 0xff,
0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f,
0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0x7f, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x3f, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x3f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x8f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xf, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
// Byte array of bitmap of 128 x 128 px:
char img[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc1, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3,
0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf, 0xf0, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xfc, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xfe, 0xf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x1f, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff,
0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xfe,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf,
0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xc7,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc0, 0x3, 0xff, 0xff, 0xe3, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xfe, 0xf, 0xf0, 0x7f, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc7, 0xff, 0xfe, 0x1f, 0xf8, 0x7f, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xcf, 0xff, 0xfc, 0x7f, 0xfe, 0x3f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff,
0xf8, 0x7f, 0xfe, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xf8, 0xff,
0xff, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f,
0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xf3, 0xff, 0xff, 0xcf, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x9f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x1f, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff,
0xf1, 0xff, 0xff, 0x8f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf1, 0xff,
0xff, 0x8f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf8, 0xff, 0xff, 0x1f,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xf8, 0x7f, 0xfe, 0x1f, 0xff, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfc, 0x3f, 0xfc, 0x3f, 0xff, 0xf8, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xfe, 0x1f, 0xf8, 0x7f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0x7, 0xe0, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x8f, 0xff, 0xff, 0x80, 0x1, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x8f, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff,
0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xff, 0x9f, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xc0, 0xff, 0xff, 0x7, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x8f, 0xff, 0x80, 0xff, 0xff, 0x3, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc7, 0xff, 0x80, 0x0, 0x0, 0x1, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff,
0x18, 0x0, 0x0, 0x10, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xfe, 0x18, 0x0,
0x0, 0x18, 0x7f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xfc, 0x3f, 0xff, 0xff, 0xfc,
0x7f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xc7,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf8, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xc7, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe3, 0xf1, 0xff, 0xe0, 0x3f, 0xff, 0x8f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf1, 0xe1, 0xfc, 0x0, 0x1, 0xff, 0x8f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf1, 0xe3, 0xf0, 0x0, 0x0, 0x7f, 0xc7, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xc7,
0xf0, 0x3f, 0xe0, 0x3f, 0xc3, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xc7, 0xf1, 0xff,
0xfe, 0x3f, 0xe3, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x8f, 0xf1, 0xff, 0xfe, 0x7f,
0xf1, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf, 0xf1, 0xff, 0xfc, 0x7f, 0xf1, 0x1f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xf1, 0xff, 0xfc, 0x7f, 0xf8, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xf9, 0xff, 0xfc, 0x7f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xf8, 0xff, 0xfc, 0x7f, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x7f, 0xf8, 0xff, 0xf8, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f,
0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xf1, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f,
0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x8f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xf, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
int
connect_n_send(void)
{
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return -1;
}
@ -213,29 +192,29 @@ connect_n_send(void)
assert(req);
memset(req, 0, REQ_MAX);
sprintf(req, GET_REQUEST, "empty");
// char *req = (char *)malloc(POST_MAX);
// assert(req);
// memset(req, 0, POST_MAX);
// sprintf(req, POST_REQUEST, "HELLO", sizeof(img));
// char *req = (char *)malloc(POST_MAX);
// assert(req);
// memset(req, 0, POST_MAX);
// sprintf(req, POST_REQUEST, "HELLO", sizeof(img));
int len = strlen(req);
// memcpy(req+len, img, sizeof(img));
// strcat(req+len+sizeof(img), POST_REQUEST_END);
// len += sizeof(img) + strlen(POST_REQUEST_END);
// memcpy(req+len, img, sizeof(img));
// strcat(req+len+sizeof(img), POST_REQUEST_END);
// len += sizeof(img) + strlen(POST_REQUEST_END);
char *resp = (char *)malloc(RESP_MAX);
assert(resp);
memset(resp, 0, RESP_MAX);
// int fd = open("tmp_cli.png", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXO | S_IRWXG);
// if (fd < 0) {
// perror("open");
// goto skip;
// }
//
// int sz = write(fd, img, sizeof(img));
// if (sz < 0) {
// perror("write");
// }
// close(fd);
// int fd = open("tmp_cli.png", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXO | S_IRWXG);
// if (fd < 0) {
// perror("open");
// goto skip;
// }
//
// int sz = write(fd, img, sizeof(img));
// if (sz < 0) {
// perror("write");
// }
// close(fd);
skip:
printf("Sending..\n");

@ -28,12 +28,12 @@ struct request {
static char *
remove_spaces(char *str)
{
int i = 0;
while (isspace(*str)) str++;
i = strlen(str);
while (isspace(str[i-1])) str[i-1]='\0';
int i = 0;
while (isspace(*str)) str++;
i = strlen(str);
while (isspace(str[i - 1])) str[i - 1] = '\0';
return str;
return str;
}
void *
@ -41,8 +41,8 @@ send_fn(void *d)
{
struct request *r = (struct request *)d;
char resp[STR_MAX] = { 0 };
int fd = -1;
char resp[STR_MAX] = { 0 };
int fd = -1;
struct sockaddr_in sa;
sa.sin_family = AF_INET;
@ -53,17 +53,14 @@ send_fn(void *d)
return NULL;
}
if (sendto(fd, r->msg, strlen(r->msg), 0, (struct sockaddr*)&sa, sizeof(sa)) < 0 &&
errno != EINTR) {
if (sendto(fd, r->msg, strlen(r->msg), 0, (struct sockaddr *)&sa, sizeof(sa)) < 0 && errno != EINTR) {
perror("sendto");
return NULL;
}
//todo: select rcv from!
// todo: select rcv from!
int sa_len = sizeof(sa);
if (recvfrom(fd, resp, STR_MAX, 0, (struct sockaddr *)&sa, &sa_len) < 0) {
perror("recvfrom");
}
if (recvfrom(fd, resp, STR_MAX, 0, (struct sockaddr *)&sa, &sa_len) < 0) { perror("recvfrom"); }
printf("Done[%s]!\n", resp);
close(fd);
free(r);
@ -71,9 +68,9 @@ send_fn(void *d)
return NULL;
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: %s <sandbox_file>\n", argv[0]);
return -1;
@ -91,7 +88,7 @@ int main(int argc, char *argv[])
char line[MSG_MAX] = { 0 };
while (fgets(line, MSG_MAX, f) != NULL) {
char *msg = NULL, *tok, *src = line;
char ip[STR_MAX] = { 0 }, port[STR_MAX] = { 0 };
char ip[STR_MAX] = { 0 }, port[STR_MAX] = { 0 };
src = remove_spaces(src);
if (src[0] == ';') goto next;
@ -120,7 +117,7 @@ int main(int argc, char *argv[])
goto next;
}
next:
next:
memset(line, 0, MSG_MAX);
fflush(stdin);
fflush(stdout);
@ -128,6 +125,6 @@ next:
}
fclose(f);
return 0;
}

Loading…
Cancel
Save