Skip to content

Commit

Permalink
Add threading and lock prefix support
Browse files Browse the repository at this point in the history
This change breaks the build for non-Linux systems temporarily until we
can polyfill the gettid() function.
  • Loading branch information
jart committed Nov 11, 2022
1 parent 99f3ec0 commit 98031c3
Show file tree
Hide file tree
Showing 62 changed files with 1,354 additions and 726 deletions.
5 changes: 5 additions & 0 deletions bench.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ fi
)

tests="
$HOME/cosmo/o/test/libc/intrin/pthread_spin_lock_test.com
$HOME/cosmo/o/test/libc/intrin/pthread_mutex_lock_test.com
$HOME/cosmo/o/test/libc/intrin/pthread_mutex_lock2_test.com
$HOME/cosmo/o/test/libc/intrin/lock_test.com
$HOME/cosmo/o/test/libc/intrin/lockscale_test.com
$HOME/cosmo/o/test/libc/intrin/kprintf_test.com
$HOME/cosmo/o/test/libc/intrin/intrin_test.com
$HOME/cosmo/o/test/libc/intrin/countbits_test.com
Expand Down
1 change: 0 additions & 1 deletion blink/address.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "blink/builtin.h"
#include "blink/endian.h"
#include "blink/modrm.h"
#include "blink/throw.h"
#include "blink/x86.h"

uint64_t AddressOb(struct Machine *m, uint32_t rde) {
Expand Down
1 change: 0 additions & 1 deletion blink/alu.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "blink/alu.h"
#include "blink/endian.h"
#include "blink/flags.h"
#include "blink/throw.h"

const aluop_f kAlu[12][4] = {
{Add8, Add16, Add32, Add64}, {Or8, Or16, Or32, Or64},
Expand Down
23 changes: 23 additions & 0 deletions blink/alu.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
#define BSU_SAL 6
#define BSU_SAR 7

#define ALU_INT8 0
#define ALU_INT16 1
#define ALU_INT32 2
#define ALU_INT64 3

typedef int64_t (*aluop_f)(uint64_t, uint64_t, uint32_t *);

extern const aluop_f kAlu[12][4];
Expand Down Expand Up @@ -105,6 +110,24 @@ int64_t Rcl64(uint64_t, uint64_t, uint32_t *);

uint64_t BsuDoubleShift(int, uint64_t, uint64_t, uint8_t, bool, uint32_t *);

void OpAluw(struct Machine *, uint32_t);
void OpXaddEbGb(struct Machine *, uint32_t);
void OpXaddEvqpGvqp(struct Machine *, uint32_t);
void Op0fe(struct Machine *, uint32_t);
void OpNegEb(struct Machine *, uint32_t);
void OpNotEb(struct Machine *, uint32_t);
void OpAlubAdd(struct Machine *, uint32_t);
void OpAlubOr(struct Machine *, uint32_t);
void OpAlubAdc(struct Machine *, uint32_t);
void OpAlubSbb(struct Machine *, uint32_t);
void OpAlubAnd(struct Machine *, uint32_t);
void OpAlubSub(struct Machine *, uint32_t);
void OpAlubXor(struct Machine *, uint32_t);
void OpNotEvqp(struct Machine *, uint32_t);
void OpNegEvqp(struct Machine *, uint32_t);
void OpIncEvqp(struct Machine *, uint32_t);
void OpDecEvqp(struct Machine *, uint32_t);

void OpDas(struct Machine *, uint32_t);
void OpAaa(struct Machine *, uint32_t);
void OpAas(struct Machine *, uint32_t);
Expand Down
122 changes: 122 additions & 0 deletions blink/alu1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include <limits.h>
#include <stdatomic.h>

#include "blink/alu.h"
#include "blink/assert.h"
#include "blink/endian.h"
#include "blink/flags.h"
#include "blink/modrm.h"
#include "blink/swap.h"

static void AluEb(struct Machine *m, uint32_t rde, aluop_f op) {
uint8_t *p;
p = GetModrmRegisterBytePointerWrite(m, rde);
if (!Lock(rde)) {
Write8(p, op(Read8(p), 0, &m->flags));
} else {
#if !defined(__riscv) && !defined(__MICROBLAZE__)
uint8_t x, z;
x = Read8(p);
do {
z = op(x, 0, &m->flags);
} while (!atomic_compare_exchange_weak((atomic_uchar *)p, &x, z));
#else
OpUd(m, rde);
#endif
}
}

void OpNotEb(struct Machine *m, uint32_t rde) {
AluEb(m, rde, Not8);
}

void OpNegEb(struct Machine *m, uint32_t rde) {
AluEb(m, rde, Neg8);
}

void Op0fe(struct Machine *m, uint32_t rde) {
switch (ModrmReg(rde)) {
case 0:
AluEb(m, rde, Inc8);
break;
case 1:
AluEb(m, rde, Dec8);
break;
default:
OpUd(m, rde);
}
}

static void AluEvqp(struct Machine *m, uint32_t rde, const aluop_f ops[4]) {
uint8_t *p;
if (Rexw(rde)) {
p = GetModrmRegisterWordPointerWrite(m, rde, 8);
if (Lock(rde) && !((intptr_t)p & 7)) {
#if LONG_BIT == 64
uint64_t x, z;
x = atomic_load((atomic_ulong *)p);
do {
z = ops[ALU_INT64](SWAP64LE(x), 0, &m->flags);
z = SWAP64LE(z);
} while (!atomic_compare_exchange_weak((atomic_ulong *)p, &x, z));
#else
OpUd(m, rde);
#endif
} else {
Write64(p, ops[ALU_INT64](Read64(p), 0, &m->flags));
}
} else if (!Osz(rde)) {
uint32_t x, z;
p = GetModrmRegisterWordPointerWrite(m, rde, 4);
if (Lock(rde) && !((intptr_t)p & 3)) {
x = atomic_load((atomic_uint *)p);
do {
z = ops[ALU_INT32](SWAP32LE(x), 0, &m->flags);
z = SWAP32LE(z);
} while (!atomic_compare_exchange_weak((atomic_uint *)p, &x, z));
} else {
Write32(p, ops[ALU_INT32](Read32(p), 0, &m->flags));
}
if (IsModrmRegister(rde)) {
Write32(p + 4, 0);
}
} else {
unassert(!Lock(rde));
p = GetModrmRegisterWordPointerWrite(m, rde, 2);
Write16(p, ops[ALU_INT16](Read16(p), 0, &m->flags));
}
}

void OpNotEvqp(struct Machine *m, uint32_t rde) {
AluEvqp(m, rde, kAlu[ALU_NOT]);
}

void OpNegEvqp(struct Machine *m, uint32_t rde) {
AluEvqp(m, rde, kAlu[ALU_NEG]);
}

void OpIncEvqp(struct Machine *m, uint32_t rde) {
AluEvqp(m, rde, kAlu[ALU_INC]);
}

void OpDecEvqp(struct Machine *m, uint32_t rde) {
AluEvqp(m, rde, kAlu[ALU_DEC]);
}
133 changes: 133 additions & 0 deletions blink/alu2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include <limits.h>
#include <stdatomic.h>

#include "blink/alu.h"
#include "blink/assert.h"
#include "blink/endian.h"
#include "blink/flags.h"
#include "blink/modrm.h"
#include "blink/swap.h"

static void Alub(struct Machine *m, uint32_t rde, aluop_f op) {
uint8_t *p, *q;
p = GetModrmRegisterBytePointerWrite(m, rde);
q = ByteRexrReg(m, rde);
if (!Lock(rde)) {
Write8(p, op(Read8(p), Read8(q), &m->flags));
} else {
#if !defined(__riscv) && !defined(__MICROBLAZE__)
uint8_t x, y, z;
x = Read8(p);
y = Read8(q);
do {
z = op(x, y, &m->flags);
} while (!atomic_compare_exchange_weak((atomic_uchar *)p, &x, z));
#else
OpUd(m, rde);
#endif
}
}

void OpAlubAdd(struct Machine *m, uint32_t rde) {
Alub(m, rde, Add8);
}

void OpAlubOr(struct Machine *m, uint32_t rde) {
Alub(m, rde, Or8);
}

void OpAlubAdc(struct Machine *m, uint32_t rde) {
Alub(m, rde, Adc8);
}

void OpAlubSbb(struct Machine *m, uint32_t rde) {
Alub(m, rde, Sbb8);
}

void OpAlubAnd(struct Machine *m, uint32_t rde) {
Alub(m, rde, And8);
}

void OpAlubSub(struct Machine *m, uint32_t rde) {
Alub(m, rde, Sub8);
}

void OpAlubXor(struct Machine *m, uint32_t rde) {
Alub(m, rde, Xor8);
}

void OpAluw(struct Machine *m, uint32_t rde) {
uint8_t *p, *q;
q = RegRexrReg(m, rde);
if (Rexw(rde)) {
uint64_t x, y, z;
p = GetModrmRegisterWordPointerWrite(m, rde, 8);
if (Lock(rde) && !((intptr_t)p & 7)) {
#if LONG_BIT == 64
x = atomic_load((atomic_ulong *)p);
y = atomic_load_explicit((atomic_ulong *)q, memory_order_relaxed);
y = SWAP64LE(y);
do {
z = kAlu[(m->xedd->op.opcode & 070) >> 3][ALU_INT64](SWAP64LE(x), y,
&m->flags);
z = SWAP64LE(z);
} while (!atomic_compare_exchange_weak((atomic_ulong *)p, &x, z));
#else
OpUd(m, rde);
#endif
} else {
x = Read64(p);
y = Read64(q);
z = kAlu[(m->xedd->op.opcode & 070) >> 3][ALU_INT64](x, y, &m->flags);
Write64(p, z);
}
} else if (!Osz(rde)) {
uint32_t x, y, z;
p = GetModrmRegisterWordPointerWrite(m, rde, 4);
if (Lock(rde) && !((intptr_t)p & 3)) {
x = atomic_load((atomic_uint *)p);
y = atomic_load_explicit((atomic_uint *)q, memory_order_relaxed);
y = SWAP32LE(y);
do {
z = kAlu[(m->xedd->op.opcode & 070) >> 3][ALU_INT32](SWAP32LE(x), y,
&m->flags);
z = SWAP32LE(z);
} while (!atomic_compare_exchange_weak((atomic_uint *)p, &x, z));
} else {
x = Read32(p);
y = Read32(q);
z = kAlu[(m->xedd->op.opcode & 070) >> 3][ALU_INT32](x, y, &m->flags);
Write32(p, z);
}
Write32(q + 4, 0);
if (IsModrmRegister(rde)) {
Write32(p + 4, 0);
}
} else {
uint16_t x, y, z;
unassert(!Lock(rde));
p = GetModrmRegisterWordPointerWrite(m, rde, 2);
x = Read16(p);
y = Read16(q);
z = kAlu[(m->xedd->op.opcode & 070) >> 3][ALU_INT16](x, y, &m->flags);
Write16(p, z);
}
}
7 changes: 0 additions & 7 deletions blink/argv.h

This file was deleted.

4 changes: 2 additions & 2 deletions blink/blink.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
#include "blink/case.h"
#include "blink/endian.h"
#include "blink/loader.h"
#include "blink/log.h"
#include "blink/machine.h"
#include "blink/macros.h"
#include "blink/signal.h"
#include "blink/syscall.h"
#include "blink/xlat.h"

struct Machine *m;
Expand Down Expand Up @@ -66,7 +66,7 @@ static int Exec(char *prog, char **argv, char **envp) {
m->system->fds = o->system->fds;
FreeMachine(o);
}
if (!(rc = setjmp(m->system->onhalt))) {
if (!(rc = setjmp(m->onhalt))) {
for (;;) {
LoadInstruction(m);
ExecuteInstruction(m);
Expand Down
7 changes: 0 additions & 7 deletions blink/clmul.h

This file was deleted.

Loading

0 comments on commit 98031c3

Please sign in to comment.