From e6d786a403a36b98e4f6082ee9848473825db8e8 Mon Sep 17 00:00:00 2001 From: LAN-TW Date: Sat, 16 Nov 2013 02:33:03 +0800 Subject: =?UTF-8?q?HW2:=20big=5Fjudge=20=E5=A4=A7=E8=87=B4=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E9=81=8B=E4=BD=9C=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw2/big_judge.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- hw2/judge.c | 5 +++ hw2/logger.c | 22 ++++++++++-- hw2/logger.h | 1 + hw2/xwrap.c | 3 ++ 5 files changed, 134 insertions(+), 4 deletions(-) (limited to 'hw2') 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 +#include +#include #include #include #include @@ -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; } -- cgit v1.2.3