summaryrefslogtreecommitdiffstats
path: root/hw2
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-11-16 02:33:03 +0800
committerLAN-TW <lantw44@gmail.com>2013-11-16 02:33:03 +0800
commite6d786a403a36b98e4f6082ee9848473825db8e8 (patch)
tree9dbff1670f9a30e64c6b0fe6a3f2fcd36da67173 /hw2
parentfd5eea92e3f2337e5fd5f336863e5356eda4226f (diff)
downloadsp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar
sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.gz
sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.bz2
sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.lz
sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.xz
sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.zst
sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.zip
HW2: big_judge 大致可以運作了
Diffstat (limited to 'hw2')
-rw-r--r--hw2/big_judge.c107
-rw-r--r--hw2/judge.c5
-rw-r--r--hw2/logger.c22
-rw-r--r--hw2/logger.h1
-rw-r--r--hw2/xwrap.c3
5 files changed, 134 insertions, 4 deletions
diff --git a/hw2/big_judge.c b/hw2/big_judge.c
index 92ca701..05077a7 100644
--- a/hw2/big_judge.c
+++ b/hw2/big_judge.c
@@ -7,6 +7,8 @@
#include "xwrap.h"
#include <errno.h>
+#include <poll.h>
+#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -18,13 +20,15 @@ typedef struct {
pid_t pid;
int read;
int write;
+ bool working;
+ XBuf buf;
} JudgeData;
typedef struct {
long score;
} PlayerData;
-bool comb4 (Comp135* comp, int players[], long player_num) {
+static bool comb4 (int players[], long player_num) {
for (int i = 3; i >= 0; i--) {
if (players[i] + 1 <= player_num &&
players[i] + 1 + (3 - i) <= player_num) {
@@ -38,6 +42,69 @@ bool comb4 (Comp135* comp, int players[], long player_num) {
return false;
}
+static int nextjudge (JudgeData* jd, long judge_num) {
+ for (int i = 0; i < judge_num; i++) {
+ if (!(jd[i].working)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int nextscore (Comp135* comp, JudgeData* jd, long judge_num,
+ PlayerData* pd, long player_num, struct pollfd* jpoll) {
+
+repoll:
+ if (poll (jpoll, judge_num, -1) <= 0) {
+ fprintf (stderr, "Poll fail: %s\n", strerror (errno));
+ return -1;
+ }
+
+ for (int i = 0; i < judge_num; i++) {
+ if (jpoll[i].revents & POLLIN || jpoll[i].revents & POLLPRI) {
+ comp135_log (comp, "Waiting for judge %d input", i + 1);
+ for (int j = 0; j < 4; j++) {
+ char* r;
+ while (
+ (r = xgetline (jpoll[i].fd, &jd[i].buf, '\n')) == NULL &&
+ !(jd[i].buf.buf_error) && !(jd[i].buf.buf_eof));
+ if (r == NULL) {
+ goto repoll;
+ }
+
+ long id, rank, scr;
+ if (sscanf (r, "%ld %ld", &id, &rank) < 2) {
+ comp135_log (comp, "Judge %d send bad input %s", i + 1, r);
+ j--;
+ continue;
+ }
+ free (r);
+
+ if (id > player_num || id <= 0) {
+ comp135_log (comp, "Bad player ID: %ld", player_num);
+ j--;
+ continue;
+ }
+ if (rank > 4 || rank < 1) {
+ comp135_log (comp, "Bad rank: %ld", rank);
+ j--;
+ continue;
+ }
+
+ scr = 4 - rank;
+ comp135_log (comp, "Player %ld gets %ld points", id, scr);
+ pd[id - 1].score += scr;
+ comp135_log (comp, "Player %ld has %ld points now", id, pd[id - 1].score);
+ }
+ comp135_log (comp, "Judge %d is available now", i + 1);
+ jd[i].working = false;
+ break;
+ }
+ }
+
+ return 0;
+}
+
int main (int argc, char* argv[]) {
if (argc < 3) {
fprintf (stderr, "Usage: %s judge_num player_num\n", argv[0]);
@@ -64,6 +131,13 @@ int main (int argc, char* argv[]) {
return 3;
}
+ struct sigaction sa = {
+ .sa_handler = SIG_IGN,
+ .sa_flags = 0
+ };
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGPIPE, &sa, NULL);
+
Comp135 comp_struct, *comp;
comp = &comp_struct;
@@ -71,6 +145,7 @@ int main (int argc, char* argv[]) {
JudgeData* jd = xmalloc (sizeof (JudgeData) * judge_num);
PlayerData* pd = xmalloc (sizeof (PlayerData) * player_num);
+ struct pollfd* jpoll = xmalloc (sizeof (struct pollfd) * judge_num);
for (int i = 0; i < player_num; i++) {
pd[i].score = 0;
@@ -96,22 +171,50 @@ int main (int argc, char* argv[]) {
} else {
close (fdr[0]);
close (fdw[1]);
+ dup2 (fdw[0], STDIN_FILENO);
+ close (fdw[0]);
+ dup2 (fdr[1], STDOUT_FILENO);
+ close (fdr[1]);
char* myjudge = xgetres ("judge");
execl (myjudge, "judge", xsprintf ("%d", i + 1), (char*)NULL);
fprintf (stderr, "%s: execl: %s: %s\n", argv[0], myjudge, strerror (errno));
_exit (1);
}
+ jpoll[i].fd = fdr[0];
+ jpoll[i].events = POLLIN | POLLPRI;
+ jpoll[i].revents = 0;
jd[i].read = fdr[0];
jd[i].write = fdw[1];
+ jd[i].working = false;
+ xbufinit (&jd[i].buf);
comp135_log (comp, "Judge %d created: PID = %u, read = %d, write = %d",
i + 1, jd[i].pid, jd[i].read, jd[i].write);
}
int players[4] = {1, 2, 3, 4};
+ long completed_jobs = 0;
do {
+ char msg[20];
+ int msglen;
+ int jnext;
+ msglen = snprintf (msg, 20, "%d %d %d %d\n",
+ players[0], players[1], players[2], players[3]);
+
+ while ((jnext = nextjudge (jd, judge_num)) < 0) {
+ if (nextscore (comp, jd, judge_num, pd, player_num, jpoll) < 0) {
+ continue;
+ }
+ completed_jobs++;
+ }
+
+ comp135_log (comp, "Send %d %d %d %d to judge %d",
+ players[0], players[1], players[2], players[3], jnext + 1);
+ write (jd[jnext].write, msg, msglen);
+ comp135_log (comp, "Judge %d is working now", jnext + 1);
+ jd[jnext].working = true;
- } while (comb4 (comp, players, player_num));
+ } while (comb4 (players, player_num));
comp135_destroy (comp);
diff --git a/hw2/judge.c b/hw2/judge.c
index bfd8e31..02b513a 100644
--- a/hw2/judge.c
+++ b/hw2/judge.c
@@ -132,6 +132,8 @@ int main (int argc, char* argv[]) {
};
sigemptyset (&sa.sa_mask);
sigaction (SIGALRM, &sa, NULL);
+ sa.sa_handler = SIG_IGN;
+ sigaction (SIGPIPE, &sa, NULL);
char *linestr = NULL;
size_t linelen = 0;
@@ -341,8 +343,11 @@ int main (int argc, char* argv[]) {
}
for (int j = 0; j < 4; j++) {
+ comp135_log (comp, "Send %s %d to big_judge",
+ pl[j], ffd[rank[j]].rank);
printf ("%s %d\n", pl[j], ffd[rank[j]].rank);
}
+ fflush (stdout);
new_loop_end:
free (linestr);
diff --git a/hw2/logger.c b/hw2/logger.c
index 7723781..e8c2cbf 100644
--- a/hw2/logger.c
+++ b/hw2/logger.c
@@ -31,6 +31,7 @@ void comp135_init (Comp135* comp, const char* static_name, bool no_init) {
}
comp->pid = getpid ();
comp->debug = false;
+ comp->is_term = false;
const char* comp135_debug = getenv ("COMP135_DEBUG");
const char* comp135_logfile = getenv ("COMP135_LOGFILE");
@@ -49,6 +50,10 @@ void comp135_init (Comp135* comp, const char* static_name, bool no_init) {
comp->log_fd = STDERR_FILENO;
comp->log_file = stderr;
+ if (isatty (comp->log_fd)) {
+ comp->is_term = true;
+ }
+
if (comp135_logfile == NULL || *comp135_logfile == '\0') {
return;
}
@@ -59,6 +64,10 @@ void comp135_init (Comp135* comp, const char* static_name, bool no_init) {
return;
}
+ if (isatty (fd)) {
+ comp->is_term = true;
+ }
+
FILE* fp = fdopen (fd, "wb");
if (fp == NULL) {
close (fd);
@@ -101,11 +110,20 @@ void comp135_log (Comp135* comp, const char* format, ...) {
};
fcntl (comp->log_fd, F_SETLKW, &lock_info);
+ char pid_color[] = "\033[1;44;37m";
+ pid_color[5] = comp->pid % 6 + '1';
fprintf (comp->log_file,
- "%04d-%02d-%02d %02d:%02d:%02d %s[%d]: ",
+ "%s%04d-%02d-%02d %s%02d:%02d:%02d %s%s[%s%d%s]: %s",
+ comp->is_term ? "\033[31m" : "",
tmd.tm_year + 1900, tmd.tm_mon + 1, tmd.tm_mday,
+ comp->is_term ? "\033[32m" : "",
tmd.tm_hour, tmd.tm_min, tmd.tm_sec,
- comp->name, comp->pid);
+ comp->is_term ? "\033[33m" : "",
+ comp->name,
+ comp->is_term ? pid_color : "",
+ comp->pid,
+ comp->is_term ? "\033[0m\033[33m" : "",
+ comp->is_term ? "\033[0m" : "");
va_list ap;
va_start (ap, format);
diff --git a/hw2/logger.h b/hw2/logger.h
index 2e58930..e16bb3f 100644
--- a/hw2/logger.h
+++ b/hw2/logger.h
@@ -12,6 +12,7 @@ typedef struct {
int log_fd;
FILE* log_file;
int debug : 1;
+ int is_term : 1;
} Comp135;
void comp135_init (Comp135* comp, const char* static_name, bool no_init);
diff --git a/hw2/xwrap.c b/hw2/xwrap.c
index f43d029..4f0d92b 100644
--- a/hw2/xwrap.c
+++ b/hw2/xwrap.c
@@ -352,6 +352,9 @@ char* xgetline (int fd, XBuf* buf, int delim) {
/* delim is found */
char* newstr = buf->buf_line;
buf->buf_line = NULL;
+ buf->buf_line_len = 0;
+ memmove (buf->buf, buf->buf + buf->buf_start, buf->buf_len);
+ buf->buf_start = 0;
return newstr;
}