-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathapp.c
154 lines (132 loc) · 3.93 KB
/
app.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdio.h>
#include <stdlib.h>
#include <stdnoreturn.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "app.h"
#include "protocol.h"
#include "quad.h"
#include "symtable.h"
#include "threadpool.h"
#include "vec.h"
#include "lib.h"
// Used to look up unmangled IDs with scoping
struct symtable *scoped_id_table;
// Used to store IDs with mangled names
struct symtable *flat_id_table;
// Used throughout to save memory with string constants
struct symtable *stringconst_table;
// Used by the parser to save memory with ID names
struct symtable *id_name_table;
extern vec_t quad_array;
int error_count = 0;
extern struct symnode *main_func_symnode;
void discard_file(void *filename) {
char *file = (char *)filename;
info("removing %s", file);
CHK(unlink(file));
}
void launch_qtspim(void *filename) {
int status;
switch (fork()) {
case -1:
panic("fork on qtspim failed");
case 0:
execlp("qtspim", "qtspim", "-file", (char *)filename, NULL);
panic("execlp on qtspim failed");
}
CHK(wait(&status));
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != EXIT_SUCCESS) {
panic("qtspim exited with status %d", WEXITSTATUS(status));
}
} else if (WIFSIGNALED(status)) {
panic("qtspim terminated by signal %d", WTERMSIG(status));
} else {
panic("qtspim terminated abnormally");
}
}
int run_app(const struct cmd_args *args) {
// one thread because we should be able to kill qtspim without exiting our app
// but not the other way around (qtspim should not be able to kill our app)
// two queued jobs max because we don't want to launch qtspim after the file
// is removed
// might work with only one queued job max, but this is safer
#define THREAD 1
#define QUEUE 2
int status = EXIT_SUCCESS;
threadpool_t pool = threadpool_create(THREAD, QUEUE, 0);
if (pool == NULL) panic("failed to create threadpool");
extern FILE *yyin, *yyout;
extern int yyparse(void);
// open input and output files
yyin = fopen(args->filename, "r");
if (yyin == NULL) panic("failed to open input file");
yyout = fopen(args->output, "w");
if (yyout == NULL) panic("failed to open output file");
id_name_table = symtable_new();
quad_array = vec_new();
#ifdef YYDEBUG
extern int yydebug;
yydebug = 1;
#endif
// launch yyparse
if (yyparse() != 0) {
printf("error\n");
status = EXIT_FAILURE;
}
if (args->stdisplay) symtable_display(id_name_table);
if (args->verbose) quad_vec_display();
generate_asm(yyout);
CHK(fclose(yyin));
CHK(fclose(yyout));
// launch qtspim
if (!args->no_exe) {
switch (threadpool_add(pool, launch_qtspim, args->output, 0)) {
case 0:
break;
case threadpool_invalid:
panic("invalid threadpool (threadpool seems to be NULL)");
case threadpool_lock_failure:
panic("lock failure on threadpool");
case threadpool_queue_full:
panic("queue is full");
case threadpool_shutdown:
panic("threadpool is shutting down");
default:
panic("unknown error on threadpool");
}
}
if (args->dispose_on_exit) {
switch (threadpool_add(pool, discard_file, args->output, 0)) {
case 0:
break;
case threadpool_invalid:
panic("invalid threadpool (threadpool seems to be NULL)");
case threadpool_lock_failure:
panic("lock failure on threadpool");
case threadpool_queue_full:
panic("queue is full");
case threadpool_shutdown:
panic("threadpool is shutting down");
default:
panic("unknown error on threadpool");
}
}
// wait for tasks to finish (blocking)
switch (threadpool_destroy(pool, 1)) {
case 0:
break;
case threadpool_invalid:
panic("invalid threadpool (threadpool seems to be NULL)");
case threadpool_lock_failure:
panic("lock failure on threadpool");
case threadpool_shutdown:
panic("threadpool is shutting down");
default:
panic("unknown error on threadpool");
}
return status;
}