mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Add a turfwar hilbert decoration
This commit is contained in:
parent
a6586cafb2
commit
6dcdf91458
9 changed files with 186 additions and 81 deletions
21
libc/ar.h
Normal file
21
libc/ar.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_AR_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_AR_H_
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#define ARMAG "!<arch>\n"
|
||||||
|
#define SARMAG 8
|
||||||
|
#define ARFMAG "`\n"
|
||||||
|
|
||||||
|
struct ar_hdr {
|
||||||
|
char ar_name[16];
|
||||||
|
char ar_date[12];
|
||||||
|
char ar_uid[6], ar_gid[6];
|
||||||
|
char ar_mode[8];
|
||||||
|
char ar_size[10];
|
||||||
|
char ar_fmag[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_AR_H_ */
|
4
libc/isystem/ar.h
Normal file
4
libc/isystem/ar.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_AR_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_ISYSTEM_AR_H_
|
||||||
|
#include "libc/ar.h"
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_AR_H_ */
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef LIBC_ISYSTEM_STRING_H_
|
#ifndef LIBC_ISYSTEM_STRING_H_
|
||||||
#define LIBC_ISYSTEM_STRING_H_
|
#define LIBC_ISYSTEM_STRING_H_
|
||||||
#include "libc/mem/alg.h"
|
#include "libc/mem/alg.h"
|
||||||
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -785,7 +785,7 @@ syscon tcp TCP_SAVED_SYN 28 0 0 0 0 0 # get recorded syn packets
|
||||||
syscon tcp TCP_THIN_DUPACK 17 0 0 0 0 0 # what is it
|
syscon tcp TCP_THIN_DUPACK 17 0 0 0 0 0 # what is it
|
||||||
syscon tcp TCP_QUEUE_SEQ 21 0 0 0 0 0 # what is it
|
syscon tcp TCP_QUEUE_SEQ 21 0 0 0 0 0 # what is it
|
||||||
syscon tcp TCP_WINDOW_CLAMP 10 0 0 0 0 0 # what is it
|
syscon tcp TCP_WINDOW_CLAMP 10 0 0 0 0 0 # what is it
|
||||||
syscon tcp TCP_DEFER_ACCEPT 9 0 0 0 0 0 # what is it
|
syscon tcp TCP_DEFER_ACCEPT 9 0 0 0 0 0 # defer accept() until readable data has arrived
|
||||||
syscon tcp TCP_REPAIR 19 0 0 0 0 0 # what is it
|
syscon tcp TCP_REPAIR 19 0 0 0 0 0 # what is it
|
||||||
syscon tcp TCP_REPAIR_OPTIONS 22 0 0 0 0 0 # what is it
|
syscon tcp TCP_REPAIR_OPTIONS 22 0 0 0 0 0 # what is it
|
||||||
syscon tcp TCP_REPAIR_QUEUE 20 0 0 0 0 0 # what is it
|
syscon tcp TCP_REPAIR_QUEUE 20 0 0 0 0 0 # what is it
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
#include "libc/intrin/atomic.h"
|
#include "libc/intrin/atomic.h"
|
||||||
#include "libc/intrin/bits.h"
|
#include "libc/intrin/bits.h"
|
||||||
|
#include "libc/intrin/bsr.h"
|
||||||
|
#include "libc/intrin/hilbert.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/intrin/strace.internal.h"
|
#include "libc/intrin/strace.internal.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
|
@ -51,6 +53,7 @@
|
||||||
#include "libc/sock/struct/pollfd.h"
|
#include "libc/sock/struct/pollfd.h"
|
||||||
#include "libc/sock/struct/sockaddr.h"
|
#include "libc/sock/struct/sockaddr.h"
|
||||||
#include "libc/stdio/append.h"
|
#include "libc/stdio/append.h"
|
||||||
|
#include "libc/stdio/rand.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/slice.h"
|
#include "libc/str/slice.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -83,6 +86,7 @@
|
||||||
#include "third_party/nsync/note.h"
|
#include "third_party/nsync/note.h"
|
||||||
#include "third_party/nsync/time.h"
|
#include "third_party/nsync/time.h"
|
||||||
#include "third_party/sqlite3/sqlite3.h"
|
#include "third_party/sqlite3/sqlite3.h"
|
||||||
|
#include "third_party/stb/stb_image_write.h"
|
||||||
#include "third_party/zlib/zconf.h"
|
#include "third_party/zlib/zconf.h"
|
||||||
#include "third_party/zlib/zlib.h"
|
#include "third_party/zlib/zlib.h"
|
||||||
#include "tool/net/lfuncs.h"
|
#include "tool/net/lfuncs.h"
|
||||||
|
@ -93,6 +97,8 @@
|
||||||
|
|
||||||
#define PORT 8080 // default server listening port
|
#define PORT 8080 // default server listening port
|
||||||
#define CPUS 64 // number of cpus to actually use
|
#define CPUS 64 // number of cpus to actually use
|
||||||
|
#define XN 64 // plot width in pixels
|
||||||
|
#define YN 64 // plot height in pixels
|
||||||
#define WORKERS 500 // size of http client thread pool
|
#define WORKERS 500 // size of http client thread pool
|
||||||
#define SUPERVISE_MS 1000 // how often to stat() asset files
|
#define SUPERVISE_MS 1000 // how often to stat() asset files
|
||||||
#define KEEPALIVE_MS 60000 // max time to keep idle conn open
|
#define KEEPALIVE_MS 60000 // max time to keep idle conn open
|
||||||
|
@ -101,7 +107,8 @@
|
||||||
#define SCORE_D_UPDATE_MS 30000 // how often to regenerate /score/day
|
#define SCORE_D_UPDATE_MS 30000 // how often to regenerate /score/day
|
||||||
#define SCORE_W_UPDATE_MS 70000 // how often to regenerate /score/week
|
#define SCORE_W_UPDATE_MS 70000 // how often to regenerate /score/week
|
||||||
#define SCORE_M_UPDATE_MS 100000 // how often to regenerate /score/month
|
#define SCORE_M_UPDATE_MS 100000 // how often to regenerate /score/month
|
||||||
#define SCORE_UPDATE_MS 200000 // how often to regenerate /score
|
#define SCORE_UPDATE_MS 210000 // how often to regenerate /score
|
||||||
|
#define PLOTS_UPDATE_MS 999000 // how often to regenerate /plot/xxx
|
||||||
#define ACCEPT_DEADLINE_MS 100 // how long accept() can take to find worker
|
#define ACCEPT_DEADLINE_MS 100 // how long accept() can take to find worker
|
||||||
#define CLAIM_DEADLINE_MS 100 // how long /claim may block if queue is full
|
#define CLAIM_DEADLINE_MS 100 // how long /claim may block if queue is full
|
||||||
#define CONCERN_LOAD .75 // avoid keepalive, upon this connection load
|
#define CONCERN_LOAD .75 // avoid keepalive, upon this connection load
|
||||||
|
@ -259,6 +266,7 @@ nsync_time g_started;
|
||||||
nsync_counter g_ready;
|
nsync_counter g_ready;
|
||||||
atomic_int g_connections;
|
atomic_int g_connections;
|
||||||
nsync_note g_shutdown[3];
|
nsync_note g_shutdown[3];
|
||||||
|
int g_hilbert[YN * XN][2];
|
||||||
|
|
||||||
// whitebox metrics
|
// whitebox metrics
|
||||||
atomic_long g_banned;
|
atomic_long g_banned;
|
||||||
|
@ -330,6 +338,7 @@ struct Assets {
|
||||||
struct Asset score_month;
|
struct Asset score_month;
|
||||||
struct Asset recent;
|
struct Asset recent;
|
||||||
struct Asset favicon;
|
struct Asset favicon;
|
||||||
|
struct Asset plot[256];
|
||||||
} g_asset;
|
} g_asset;
|
||||||
|
|
||||||
// queues ListenWorker() to HttpWorker()
|
// queues ListenWorker() to HttpWorker()
|
||||||
|
@ -894,6 +903,9 @@ void *HttpWorker(void *arg) {
|
||||||
ksnprintf(ipbuf, sizeof(ipbuf), "%hhu.%hhu.%hhu.%hhu", ip >> 24, ip >> 16,
|
ksnprintf(ipbuf, sizeof(ipbuf), "%hhu.%hhu.%hhu.%hhu", ip >> 24, ip >> 16,
|
||||||
ip >> 8, ip);
|
ip >> 8, ip);
|
||||||
|
|
||||||
|
if (UrlStartsWith("/plot/") && (_rand64() % 256)) {
|
||||||
|
goto SkipSecurity;
|
||||||
|
}
|
||||||
if (!ipv6 && !ContainsInt(&g_whitelisted, ip) &&
|
if (!ipv6 && !ContainsInt(&g_whitelisted, ip) &&
|
||||||
(tok = AcquireToken(g_tok.b, ip, TB_CIDR)) < 32) {
|
(tok = AcquireToken(g_tok.b, ip, TB_CIDR)) < 32) {
|
||||||
if (tok > 4) {
|
if (tok > 4) {
|
||||||
|
@ -910,6 +922,7 @@ void *HttpWorker(void *arg) {
|
||||||
++g_ratelimits;
|
++g_ratelimits;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
SkipSecurity:
|
||||||
|
|
||||||
// we don't support http/1.0 and http/0.9 right now
|
// we don't support http/1.0 and http/0.9 right now
|
||||||
if (msg->version != 11) {
|
if (msg->version != 11) {
|
||||||
|
@ -959,6 +972,14 @@ void *HttpWorker(void *arg) {
|
||||||
a = &g_asset.score;
|
a = &g_asset.score;
|
||||||
} else if (UrlStartsWith("/recent")) {
|
} else if (UrlStartsWith("/recent")) {
|
||||||
a = &g_asset.recent;
|
a = &g_asset.recent;
|
||||||
|
} else if (UrlStartsWith("/plot/")) {
|
||||||
|
int i, block = 0;
|
||||||
|
for (i = msg->uri.a + 6; i < msg->uri.b && isdigit(inbuf[i]); ++i) {
|
||||||
|
block *= 10;
|
||||||
|
block += inbuf[i] - '0';
|
||||||
|
block &= 255;
|
||||||
|
}
|
||||||
|
a = g_asset.plot + block;
|
||||||
} else {
|
} else {
|
||||||
a = 0;
|
a = 0;
|
||||||
}
|
}
|
||||||
|
@ -1483,6 +1504,68 @@ OnError:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generator function for the big board
|
||||||
|
bool GeneratePlot(struct Asset *out, long block, long cash) {
|
||||||
|
_Static_assert(IS2POW(XN * YN), "area must be 2-power");
|
||||||
|
_Static_assert(XN == YN, "hilbert algorithm needs square");
|
||||||
|
int rc, out_len;
|
||||||
|
sqlite3 *db = 0;
|
||||||
|
struct Asset a = {0};
|
||||||
|
unsigned char *rgba;
|
||||||
|
sqlite3_stmt *stmt = 0;
|
||||||
|
unsigned x, y, i, ip, area, mask, clump;
|
||||||
|
DEBUG("GeneratePlot %ld\n", block);
|
||||||
|
a.type = "image/png";
|
||||||
|
a.cash = cash;
|
||||||
|
a.mtim = timespec_real();
|
||||||
|
FormatUnixHttpDateTime(a.lastmodified, a.mtim.tv_sec);
|
||||||
|
CHECK_MEM((rgba = calloc(4, YN * XN)));
|
||||||
|
for (y = 0; y < YN; ++y) {
|
||||||
|
for (x = 0; x < XN; ++x) {
|
||||||
|
rgba[y * XN * 4 + x * 4 + 0] = 255;
|
||||||
|
rgba[y * XN * 4 + x * 4 + 1] = 255;
|
||||||
|
rgba[y * XN * 4 + x * 4 + 2] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK_SQL(DbOpen("db.sqlite3", &db));
|
||||||
|
CHECK_DB(DbPrepare(db, &stmt,
|
||||||
|
"SELECT ip\n"
|
||||||
|
" FROM land\n"
|
||||||
|
"WHERE ip >= ?1\n"
|
||||||
|
" AND ip <= ?2"));
|
||||||
|
CHECK_DB(sqlite3_bind_int64(stmt, 1, block << 24 | 0x000000));
|
||||||
|
CHECK_DB(sqlite3_bind_int64(stmt, 2, block << 24 | 0xffffff));
|
||||||
|
CHECK_SQL(sqlite3_exec(db, "BEGIN TRANSACTION", 0, 0, 0));
|
||||||
|
area = XN * YN;
|
||||||
|
mask = area - 1;
|
||||||
|
clump = 32 - _bsr(area) - 8;
|
||||||
|
while ((rc = DbStep(stmt)) != SQLITE_DONE) {
|
||||||
|
if (rc != SQLITE_ROW) CHECK_DB(rc);
|
||||||
|
ip = sqlite3_column_int64(stmt, 0);
|
||||||
|
i = (ip >> clump) & mask;
|
||||||
|
y = g_hilbert[i][0];
|
||||||
|
x = g_hilbert[i][1];
|
||||||
|
if (rgba[y * XN * 4 + x * 4 + 3] < 255) {
|
||||||
|
++rgba[y * XN * 4 + x * 4 + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK_SQL(sqlite3_exec(db, "END TRANSACTION", 0, 0, 0));
|
||||||
|
CHECK_DB(sqlite3_finalize(stmt));
|
||||||
|
CHECK_SQL(sqlite3_close(db));
|
||||||
|
a.data.p = (char *)stbi_write_png_to_mem(rgba, XN * 4, XN, YN, 4, &out_len);
|
||||||
|
a.data.n = out_len;
|
||||||
|
a.gzip = Gzip(a.data);
|
||||||
|
free(rgba);
|
||||||
|
*out = a;
|
||||||
|
return true;
|
||||||
|
OnError:
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_close(db);
|
||||||
|
free(a.data.p);
|
||||||
|
free(rgba);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// single thread for regenerating the user scores json
|
// single thread for regenerating the user scores json
|
||||||
void *ScoreWorker(void *arg) {
|
void *ScoreWorker(void *arg) {
|
||||||
BlockSignals();
|
BlockSignals();
|
||||||
|
@ -1562,6 +1645,26 @@ void *ScoreMonthWorker(void *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// single thread for regenerating /8 cell background image charts
|
||||||
|
void *PlotWorker(void *arg) {
|
||||||
|
long i, wait;
|
||||||
|
BlockSignals();
|
||||||
|
pthread_setname_np(pthread_self(), "Plotter");
|
||||||
|
LOG("%P Plotter started\n");
|
||||||
|
wait = PLOTS_UPDATE_MS;
|
||||||
|
for (i = 0; i < 256; ++i) {
|
||||||
|
Update(g_asset.plot + i, GeneratePlot, i, MS2CASH(wait));
|
||||||
|
}
|
||||||
|
nsync_counter_add(g_ready, -1); // #6
|
||||||
|
do {
|
||||||
|
for (i = 0; i < 256; ++i) {
|
||||||
|
Update(g_asset.plot + i, GeneratePlot, i, MS2CASH(wait));
|
||||||
|
}
|
||||||
|
} while (!nsync_note_wait(g_shutdown[1], WaitFor(wait)));
|
||||||
|
LOG("Plotter exiting\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// thread for realtime json generation of recent successful claims
|
// thread for realtime json generation of recent successful claims
|
||||||
void *RecentWorker(void *arg) {
|
void *RecentWorker(void *arg) {
|
||||||
bool once;
|
bool once;
|
||||||
|
@ -1629,7 +1732,7 @@ StartOver:
|
||||||
free(f[1]);
|
free(f[1]);
|
||||||
// handle startup condition
|
// handle startup condition
|
||||||
if (!warmedup) {
|
if (!warmedup) {
|
||||||
nsync_counter_add(g_ready, -1); // #6
|
nsync_counter_add(g_ready, -1); // #7
|
||||||
warmedup = true;
|
warmedup = true;
|
||||||
}
|
}
|
||||||
// wait for wakeup or cancel
|
// wait for wakeup or cancel
|
||||||
|
@ -1676,7 +1779,7 @@ StartOver:
|
||||||
" OR created IS NULL\n"
|
" OR created IS NULL\n"
|
||||||
" OR ?3 - created > 3600"));
|
" OR ?3 - created > 3600"));
|
||||||
if (!warmedup) {
|
if (!warmedup) {
|
||||||
nsync_counter_add(g_ready, -1); // #7
|
nsync_counter_add(g_ready, -1); // #8
|
||||||
warmedup = true;
|
warmedup = true;
|
||||||
}
|
}
|
||||||
while ((n = GetClaims(&g_claims, v, BATCH_MAX))) {
|
while ((n = GetClaims(&g_claims, v, BATCH_MAX))) {
|
||||||
|
@ -1715,7 +1818,7 @@ void *NowWorker(void *arg) {
|
||||||
pthread_setname_np(pthread_self(), "NowWorker");
|
pthread_setname_np(pthread_self(), "NowWorker");
|
||||||
LOG("%P NowWorker started\n");
|
LOG("%P NowWorker started\n");
|
||||||
UpdateNow();
|
UpdateNow();
|
||||||
nsync_counter_add(g_ready, -1); // #8
|
nsync_counter_add(g_ready, -1); // #9
|
||||||
for (struct timespec ts = {timespec_real().tv_sec};; ++ts.tv_sec) {
|
for (struct timespec ts = {timespec_real().tv_sec};; ++ts.tv_sec) {
|
||||||
if (!nsync_note_wait(g_shutdown[1], ts)) {
|
if (!nsync_note_wait(g_shutdown[1], ts)) {
|
||||||
UpdateNow();
|
UpdateNow();
|
||||||
|
@ -1849,6 +1952,13 @@ int main(int argc, char *argv[]) {
|
||||||
_npassert(2 == open("turfwar.log", O_CREAT | O_WRONLY | O_APPEND, 0644));
|
_npassert(2 == open("turfwar.log", O_CREAT | O_WRONLY | O_APPEND, 0644));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG("Generating Hilbert Curve...\n");
|
||||||
|
for (int i = 0; i < YN * XN; ++i) {
|
||||||
|
axdx_t h = unhilbert(XN, i);
|
||||||
|
g_hilbert[i][0] = h.ax;
|
||||||
|
g_hilbert[i][1] = h.dx;
|
||||||
|
}
|
||||||
|
|
||||||
// library init
|
// library init
|
||||||
__enable_threads();
|
__enable_threads();
|
||||||
sqlite3_initialize();
|
sqlite3_initialize();
|
||||||
|
@ -1890,9 +2000,9 @@ int main(int argc, char *argv[]) {
|
||||||
sa.sa_handler = IgnoreSignal;
|
sa.sa_handler = IgnoreSignal;
|
||||||
sigaction(SIGUSR1, &sa, 0);
|
sigaction(SIGUSR1, &sa, 0);
|
||||||
|
|
||||||
// make 8 helper threads
|
// make 9 helper threads
|
||||||
g_ready = nsync_counter_new(9);
|
g_ready = nsync_counter_new(10);
|
||||||
pthread_t scorer, recenter, claimer, nower, replenisher;
|
pthread_t scorer, recenter, claimer, nower, replenisher, plotter;
|
||||||
pthread_t scorer_hour, scorer_day, scorer_week, scorer_month;
|
pthread_t scorer_hour, scorer_day, scorer_week, scorer_month;
|
||||||
CHECK_EQ(0, pthread_create(&scorer, 0, ScoreWorker, 0));
|
CHECK_EQ(0, pthread_create(&scorer, 0, ScoreWorker, 0));
|
||||||
CHECK_EQ(0, pthread_create(&scorer_hour, 0, ScoreHourWorker, 0));
|
CHECK_EQ(0, pthread_create(&scorer_hour, 0, ScoreHourWorker, 0));
|
||||||
|
@ -1902,10 +2012,11 @@ int main(int argc, char *argv[]) {
|
||||||
CHECK_EQ(0, pthread_create(&replenisher, 0, ReplenishWorker, 0));
|
CHECK_EQ(0, pthread_create(&replenisher, 0, ReplenishWorker, 0));
|
||||||
CHECK_EQ(0, pthread_create(&recenter, 0, RecentWorker, 0));
|
CHECK_EQ(0, pthread_create(&recenter, 0, RecentWorker, 0));
|
||||||
CHECK_EQ(0, pthread_create(&claimer, 0, ClaimWorker, 0));
|
CHECK_EQ(0, pthread_create(&claimer, 0, ClaimWorker, 0));
|
||||||
|
CHECK_EQ(0, pthread_create(&plotter, 0, PlotWorker, 0));
|
||||||
CHECK_EQ(0, pthread_create(&nower, 0, NowWorker, 0));
|
CHECK_EQ(0, pthread_create(&nower, 0, NowWorker, 0));
|
||||||
|
|
||||||
// wait for helper threads to warm up creating assets
|
// wait for helper threads to warm up creating assets
|
||||||
if (nsync_counter_add(g_ready, -1)) { // #9
|
if (nsync_counter_add(g_ready, -1)) { // #10
|
||||||
nsync_counter_wait(g_ready, nsync_time_no_deadline);
|
nsync_counter_wait(g_ready, nsync_time_no_deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1942,6 +2053,7 @@ int main(int argc, char *argv[]) {
|
||||||
LOG("Waiting for helpers to finish...\n");
|
LOG("Waiting for helpers to finish...\n");
|
||||||
CHECK_EQ(0, pthread_join(nower, 0));
|
CHECK_EQ(0, pthread_join(nower, 0));
|
||||||
CHECK_EQ(0, pthread_join(scorer, 0));
|
CHECK_EQ(0, pthread_join(scorer, 0));
|
||||||
|
CHECK_EQ(0, pthread_join(plotter, 0));
|
||||||
CHECK_EQ(0, pthread_join(recenter, 0));
|
CHECK_EQ(0, pthread_join(recenter, 0));
|
||||||
CHECK_EQ(0, pthread_join(scorer_day, 0));
|
CHECK_EQ(0, pthread_join(scorer_day, 0));
|
||||||
CHECK_EQ(0, pthread_join(scorer_hour, 0));
|
CHECK_EQ(0, pthread_join(scorer_hour, 0));
|
||||||
|
|
|
@ -38,6 +38,7 @@ NET_TURFWAR_DIRECTDEPS = \
|
||||||
THIRD_PARTY_NSYNC \
|
THIRD_PARTY_NSYNC \
|
||||||
THIRD_PARTY_NSYNC_MEM \
|
THIRD_PARTY_NSYNC_MEM \
|
||||||
THIRD_PARTY_SQLITE3 \
|
THIRD_PARTY_SQLITE3 \
|
||||||
|
THIRD_PARTY_STB \
|
||||||
THIRD_PARTY_ZLIB
|
THIRD_PARTY_ZLIB
|
||||||
|
|
||||||
NET_TURFWAR_DEPS := \
|
NET_TURFWAR_DEPS := \
|
||||||
|
|
2
third_party/stb/stb_image_write.h
vendored
2
third_party/stb/stb_image_write.h
vendored
|
@ -26,6 +26,8 @@ int stbi_write_hdr_to_func(stbi_write_func *, void *, int, int, int,
|
||||||
const float *);
|
const float *);
|
||||||
int stbi_write_jpg_to_func(stbi_write_func *, void *, int, int, int,
|
int stbi_write_jpg_to_func(stbi_write_func *, void *, int, int, int,
|
||||||
const void *, int);
|
const void *, int);
|
||||||
|
unsigned char *stbi_write_png_to_mem(const unsigned char *, int, int, int, int,
|
||||||
|
int *);
|
||||||
|
|
||||||
void stbi_flip_vertically_on_write(int);
|
void stbi_flip_vertically_on_write(int);
|
||||||
|
|
||||||
|
|
43
third_party/xed/avx.h
vendored
43
third_party/xed/avx.h
vendored
|
@ -1,43 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_THIRD_PARTY_XED_AVX_H_
|
|
||||||
#define COSMOPOLITAN_THIRD_PARTY_XED_AVX_H_
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
|
|
||||||
union XedAvxC4Payload1 {
|
|
||||||
struct {
|
|
||||||
unsigned map : 5;
|
|
||||||
unsigned b_inv : 1;
|
|
||||||
unsigned x_inv : 1;
|
|
||||||
unsigned r_inv : 1;
|
|
||||||
unsigned pad : 24;
|
|
||||||
} s;
|
|
||||||
unsigned u32;
|
|
||||||
};
|
|
||||||
|
|
||||||
union XedAvxC4Payload2 {
|
|
||||||
struct {
|
|
||||||
unsigned pp : 2;
|
|
||||||
unsigned l : 1;
|
|
||||||
unsigned vvv210 : 3;
|
|
||||||
unsigned v3 : 1;
|
|
||||||
unsigned w : 1;
|
|
||||||
unsigned pad : 24;
|
|
||||||
} s;
|
|
||||||
unsigned u32;
|
|
||||||
};
|
|
||||||
|
|
||||||
union XedAvxC5Payload {
|
|
||||||
struct {
|
|
||||||
unsigned pp : 2;
|
|
||||||
unsigned l : 1;
|
|
||||||
unsigned vvv210 : 3;
|
|
||||||
unsigned v3 : 1;
|
|
||||||
unsigned r_inv : 1;
|
|
||||||
unsigned pad : 24;
|
|
||||||
} s;
|
|
||||||
unsigned u32;
|
|
||||||
};
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* COSMOPOLITAN_THIRD_PARTY_XED_AVX_H_ */
|
|
65
third_party/xed/x86ild.greg.c
vendored
65
third_party/xed/x86ild.greg.c
vendored
|
@ -23,7 +23,6 @@
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/xed/avx.h"
|
|
||||||
#include "third_party/xed/avx512.h"
|
#include "third_party/xed/avx512.h"
|
||||||
#include "third_party/xed/private.h"
|
#include "third_party/xed/private.h"
|
||||||
#include "third_party/xed/x86.h"
|
#include "third_party/xed/x86.h"
|
||||||
|
@ -846,27 +845,32 @@ privileged static void xed_evex_imm_scanner(struct XedDecodedInst *d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
privileged static void xed_vex_c4_scanner(struct XedDecodedInst *d) {
|
privileged static void xed_vex_c4_scanner(struct XedDecodedInst *d) {
|
||||||
uint8_t n;
|
unsigned length, b1, b2;
|
||||||
xed_bits_t length, max_bytes;
|
|
||||||
union XedAvxC4Payload1 c4byte1;
|
|
||||||
union XedAvxC4Payload2 c4byte2;
|
|
||||||
if (xed_is_bound_instruction(d)) return;
|
if (xed_is_bound_instruction(d)) return;
|
||||||
length = d->length;
|
length = d->length;
|
||||||
max_bytes = d->op.max_bytes;
|
|
||||||
length++;
|
length++;
|
||||||
if (length + 2 < max_bytes) {
|
if (length + 2 < d->op.max_bytes) {
|
||||||
c4byte1.u32 = d->bytes[length];
|
// map: 5-bit
|
||||||
c4byte2.u32 = d->bytes[length + 1];
|
// rex.b: 1-bit
|
||||||
d->op.rexr = ~c4byte1.s.r_inv & 1;
|
// rex.x: 1-bit
|
||||||
d->op.rexx = ~c4byte1.s.x_inv & 1;
|
// rex.r: 1-bit
|
||||||
d->op.rexb = (xed3_mode_64b(d) & ~c4byte1.s.b_inv) & 1;
|
b1 = d->bytes[length];
|
||||||
d->op.rexw = c4byte2.s.w & 1;
|
d->op.rexr = !(b1 & 128);
|
||||||
d->op.vexdest3 = c4byte2.s.v3;
|
d->op.rexx = !(b1 & 64);
|
||||||
d->op.vexdest210 = c4byte2.s.vvv210;
|
d->op.rexb = xed3_mode_64b(d) & !(b1 & 32);
|
||||||
d->op.vl = c4byte2.s.l;
|
// prefix: 2-bit → {none, osz, rep3, rep2}
|
||||||
d->op.vex_prefix = kXed.vex_prefix_recoding[c4byte2.s.pp];
|
// vector_length: 1-bit → {xmm, ymm}
|
||||||
d->op.map = c4byte1.s.map;
|
// vexdest210: 3-bit
|
||||||
if ((c4byte1.s.map & 0x3) == XED_ILD_MAP3) {
|
// vexdest3: 1-bit
|
||||||
|
// rex.w: 1-bit
|
||||||
|
b2 = d->bytes[length + 1];
|
||||||
|
d->op.rexw = !!(b2 & 128);
|
||||||
|
d->op.vexdest3 = !!(b2 & 64);
|
||||||
|
d->op.vexdest210 = (b2 >> 3) & 7;
|
||||||
|
d->op.vl = !!(b2 & 4);
|
||||||
|
d->op.vex_prefix = kXed.vex_prefix_recoding[b2 & 3];
|
||||||
|
d->op.map = b1 & 31;
|
||||||
|
if ((b1 & 3) == XED_ILD_MAP3) {
|
||||||
d->op.imm_width = xed_bytes2bits(1);
|
d->op.imm_width = xed_bytes2bits(1);
|
||||||
}
|
}
|
||||||
d->op.vexvalid = 1;
|
d->op.vexvalid = 1;
|
||||||
|
@ -880,19 +884,22 @@ privileged static void xed_vex_c4_scanner(struct XedDecodedInst *d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
privileged static void xed_vex_c5_scanner(struct XedDecodedInst *d) {
|
privileged static void xed_vex_c5_scanner(struct XedDecodedInst *d) {
|
||||||
xed_bits_t max_bytes, length;
|
unsigned length, b;
|
||||||
union XedAvxC5Payload c5byte1;
|
|
||||||
length = d->length;
|
length = d->length;
|
||||||
max_bytes = d->op.max_bytes;
|
|
||||||
if (xed_is_bound_instruction(d)) return;
|
if (xed_is_bound_instruction(d)) return;
|
||||||
length++;
|
length++;
|
||||||
if (length + 1 < max_bytes) {
|
if (length + 1 < d->op.max_bytes) {
|
||||||
c5byte1.u32 = d->bytes[length];
|
// prefix: 2-bit → {none, osz, rep3, rep2}
|
||||||
d->op.rexr = ~c5byte1.s.r_inv & 1;
|
// vector_length: 1-bit → {xmm, ymm}
|
||||||
d->op.vexdest3 = c5byte1.s.v3;
|
// vexdest210: 3-bit
|
||||||
d->op.vexdest210 = c5byte1.s.vvv210;
|
// vexdest3: 1-bit
|
||||||
d->op.vl = c5byte1.s.l;
|
// rex.r: 1-bit
|
||||||
d->op.vex_prefix = kXed.vex_prefix_recoding[c5byte1.s.pp];
|
b = d->bytes[length];
|
||||||
|
d->op.rexr = !(b & 128);
|
||||||
|
d->op.vexdest3 = !!(b & 64);
|
||||||
|
d->op.vexdest210 = (b >> 3) & 7;
|
||||||
|
d->op.vl = (b >> 2) & 1;
|
||||||
|
d->op.vex_prefix = kXed.vex_prefix_recoding[b & 3];
|
||||||
d->op.map = XED_ILD_MAP1;
|
d->op.map = XED_ILD_MAP1;
|
||||||
d->op.vexvalid = 1;
|
d->op.vexvalid = 1;
|
||||||
length++;
|
length++;
|
||||||
|
|
Loading…
Reference in a new issue