Skip to content

Commit 24d34b7

Browse files
committed
Add the libc less example app version
1 parent 85545c3 commit 24d34b7

File tree

7 files changed

+504
-49
lines changed

7 files changed

+504
-49
lines changed

functions/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ add_subdirectory(basic)
8181
add_subdirectory(busy)
8282
add_subdirectory(matmac)
8383
add_subdirectory(matmul)
84+
add_subdirectory(example_app_nolibc)
8485
# dependent on dlibc
8586
if(USE_LIBC)
8687
# add_subdirectory(image_processing)

functions/dirigent_busy/dirigent_busy.c

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,76 @@
1010
#include "unistd.h"
1111

1212
int main(int argc, char const *argv[]) {
13-
// parse input
14-
FILE* input_data = fopen("/input/input.csv", "r");
15-
FILE* output_data = fopen("/output/output.csv", "w+");
16-
char* workload = NULL;
17-
size_t workload_size = 0;
18-
if(getdelim(&workload, &workload_size, ',', input_data) < 0) {
19-
perror("failed to read workload");
20-
return -1;
21-
}
22-
char* function = NULL;
23-
size_t function_size = 0;
24-
ssize_t string_len = 0;
25-
if((string_len = getdelim(&function, &function_size, ',', input_data) < 0)) {
26-
perror("failed to read function");
27-
return -1;
28-
}
29-
// remove ',' from end
30-
function[string_len-1] = 0;
31-
32-
char* requestedCpu = NULL;
33-
size_t requestedCpu_size = 0;
34-
if(getdelim(&requestedCpu, &requestedCpu_size, ',', input_data) < 0) {
35-
perror("failed to read requestedCpu");
36-
return -1;
37-
}
38-
char* multiplier = NULL;
39-
size_t multiplier_size = 0;
40-
if(getdelim(&multiplier, &multiplier_size, ',', input_data) < 0) {
41-
perror("failed to read multiplier");
42-
return -1;
43-
}
44-
45-
char* trace_string = "trace";
46-
char* empyt_string = "empty";
47-
char is_trace = 0;
48-
if (strcmp(trace_string, function) == 0){
49-
is_trace = 1;
50-
long multiplier_num = strtol(multiplier, NULL, 10);
51-
double result = 0.0;
52-
volatile double input = 10.0;
53-
for(long iteration = 0; iteration < multiplier_num; iteration++){
54-
result = sqrt(input);
13+
// parse input
14+
FILE *input_data = fopen("/input/input.csv", "r");
15+
if (input_data == NULL) {
16+
perror("could not open /input/input.csv");
17+
return -1;
18+
}
19+
FILE *output_data = fopen("/output/output.csv", "w+");
20+
if (output_data == NULL) {
21+
perror("could not open /output/output.csv");
22+
return -1;
23+
}
24+
25+
char *workload = NULL;
26+
size_t workload_size = 0;
27+
if (getdelim(&workload, &workload_size, ',', input_data) < 0) {
28+
perror("failed to read workload");
29+
return -1;
30+
}
31+
workload[strlen(workload) - 1] = '\0';
32+
33+
char *function = NULL;
34+
size_t function_size = 0;
35+
if (getdelim(&function, &function_size, ',', input_data) < 0) {
36+
perror("failed to read function");
37+
return -1;
38+
}
39+
function[strlen(function) - 1] = '\0';
40+
41+
char *requestedCpu = NULL;
42+
size_t requestedCpu_size = 0;
43+
if (getdelim(&requestedCpu, &requestedCpu_size, ',', input_data) < 0) {
44+
perror("failed to read requestedCpu");
45+
return -1;
46+
}
47+
requestedCpu[strlen(requestedCpu) - 1] = '\0';
48+
49+
char *multiplier = NULL;
50+
size_t multiplier_size = 0;
51+
if (getdelim(&multiplier, &multiplier_size, ',', input_data) < 0) {
52+
perror("failed to read multiplier");
53+
return -1;
5554
}
56-
fprintf(output_data,"\"OK\",\"%s\",\"dandelionServer\",%ld",function, multiplier_num);
57-
return 0;
58-
} else if(strcmp(empyt_string, function) == 0) {
59-
fprintf(output_data, "\"OK - EMPTY\",\"dandelionServer\",\"%s\",0", function);
60-
return 0;
61-
}
62-
return -1;
55+
56+
char *trace_string = "trace";
57+
char *empyt_string = "empty";
58+
59+
if (strcmp(trace_string, function) == 0) {
60+
long multiplier_num = strtol(multiplier, NULL, 10);
61+
long requested_cpu_num = strtol(requestedCpu, NULL, 10);
62+
63+
long total_iterations = multiplier_num * requested_cpu_num;
64+
65+
//printf("%ld, %ld, %ld\n", multiplier_num, requested_cpu_num, total_iterations);
66+
67+
volatile double result = 0.0;
68+
volatile double input = 10.0;
69+
volatile long iteration;
70+
for (iteration = 0; iteration < total_iterations; iteration++) {
71+
result = sqrt(input);
72+
}
73+
74+
fprintf(output_data, "\"OK\",\"%s\",\"dandelionServer\",%ld,%f", function, iteration, result);
75+
76+
return 0;
77+
} else if (strcmp(empyt_string, function) == 0) {
78+
fprintf(output_data, "\"OK - EMPTY\",\"dandelionServer\",\"%s\",0", function);
79+
80+
return 0;
81+
}
82+
83+
return -1;
84+
6385
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cmake_minimum_required(VERSION ${CMAKE_VERSION})
2+
3+
set(HANDLE "handle_nolibc")
4+
set(FAN_OUT "fan_out_nolibc")
5+
set(TEMPLATE "template_nolibc")
6+
7+
add_executable(${HANDLE}
8+
handle.c
9+
)
10+
add_executable(${FAN_OUT}
11+
fan_out.c
12+
)
13+
add_executable(${TEMPLATE}
14+
template.c
15+
)
16+
17+
target_compile_options(${HANDLE} PRIVATE -static -O3)
18+
target_link_options(${HANDLE} PRIVATE -static)
19+
target_link_libraries(${HANDLE} PRIVATE
20+
dandelion_runtime
21+
)
22+
23+
target_compile_options(${FAN_OUT} PRIVATE -static -O3)
24+
target_link_options(${FAN_OUT} PRIVATE -static)
25+
target_link_libraries(${FAN_OUT} PRIVATE
26+
dandelion_runtime
27+
)
28+
29+
target_compile_options(${TEMPLATE} PRIVATE -static -O3)
30+
target_link_options(${TEMPLATE} PRIVATE -static)
31+
target_link_libraries(${TEMPLATE} PRIVATE
32+
dandelion_runtime
33+
)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <stdint.h>
2+
3+
#include "dandelion/crt.h"
4+
#include "dandelion/runtime.h"
5+
6+
const char CHAR_NUMBERS[10] = {'0', '1', '2', '3', '4',
7+
'5', '6', '7', '8', '9'};
8+
9+
int string_copy(char* target, char* source) {
10+
size_t read_chars = 0;
11+
while (source[read_chars] != '\0') {
12+
target[read_chars] = source[read_chars];
13+
read_chars++;
14+
}
15+
return read_chars;
16+
}
17+
18+
int copy_to_string_end(char* target, char* source) {
19+
size_t read_chars = 0;
20+
while (source[read_chars] != '\"') {
21+
target[read_chars] = source[read_chars];
22+
read_chars++;
23+
}
24+
target[read_chars] = '\\';
25+
return read_chars;
26+
}
27+
28+
int skip_string(char* target, char* comparison) {
29+
size_t read_chars = 0;
30+
while (comparison[read_chars] != '\0') {
31+
if (comparison[read_chars] != target[read_chars]) return -1;
32+
read_chars++;
33+
}
34+
return read_chars;
35+
}
36+
37+
int errprint(char* message) {
38+
if (dandelion_output_set_count() < 1) {
39+
return -99;
40+
}
41+
char* stderr = dandelion_alloc(128, 8);
42+
size_t message_index = 0;
43+
for (; message[message_index] != '\0' && message_index < 127;
44+
message_index++) {
45+
stderr[message_index] = message[message_index];
46+
}
47+
stderr[message_index] = '\0';
48+
49+
const char stderr_ident[] = "stderr";
50+
struct io_buffer stderr_buffer = {
51+
.ident = stderr_ident,
52+
.ident_len = 7,
53+
.data = stderr,
54+
.data_len = message_index + 1,
55+
.key = 0,
56+
};
57+
58+
dandelion_add_output(0, stderr_buffer);
59+
60+
return -1;
61+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "commons.h"
2+
3+
const unsigned int SERVER_NUMBER = 10;
4+
5+
int main() {
6+
// make sure we have the expected output sets
7+
if (dandelion_output_set_count() < 1) return -7;
8+
9+
// read authorization server file
10+
if (dandelion_input_set_count() < 2) errprint("have less than 2 input set");
11+
if (dandelion_input_buffer_count(0) != 1)
12+
errprint("have no buffer in input set 0");
13+
if (dandelion_input_buffer_count(1) != 1)
14+
errprint("have no buffer in input set 1");
15+
16+
struct io_buffer* server_file = dandelion_get_input(0, 0);
17+
char* server_data = server_file->data;
18+
size_t server_len = server_file->data_len;
19+
20+
struct io_buffer* auth_file = dandelion_get_input(1, 0);
21+
char* auth_data = auth_file->data;
22+
size_t auth_len = auth_file->data_len;
23+
24+
// find username
25+
size_t user_start = 0;
26+
char user_prefix[] = "{\"authorized\":\"";
27+
for (size_t prefix_index = user_start; user_prefix[prefix_index] != '\0';
28+
prefix_index++) {
29+
if (auth_data[user_start] != user_prefix[prefix_index]) {
30+
return errprint("user_prefix not in actual auth message");
31+
}
32+
user_start++;
33+
}
34+
35+
size_t user_end = user_start;
36+
while (auth_data[user_end] != '\"' && user_end < auth_len) {
37+
user_end++;
38+
}
39+
40+
if (SERVER_NUMBER > 99)
41+
return errprint("More than 99 servers, need different formatting");
42+
for (size_t server_index = 0; server_index < SERVER_NUMBER; server_index++) {
43+
char* request_buffer = dandelion_alloc(2048, 8);
44+
size_t request_index = 0;
45+
char* server_name = dandelion_alloc(16, 8);
46+
char server_prefix[] = "server_";
47+
int server_name_end = string_copy(server_name, server_prefix);
48+
size_t decimal = server_index / 10;
49+
size_t digit = server_index - 10 * decimal;
50+
server_name[server_name_end] = CHAR_NUMBERS[decimal];
51+
server_name_end++;
52+
server_name[server_name_end] = CHAR_NUMBERS[digit];
53+
server_name_end++;
54+
55+
char get_prefix[] = "GET http://";
56+
request_index += string_copy(request_buffer + request_index, get_prefix);
57+
58+
for (size_t line_index = 0;
59+
line_index < server_len &&
60+
(server_data[line_index] != '\n' || server_data[line_index] != '\0');
61+
line_index++) {
62+
request_buffer[request_index] = server_data[line_index];
63+
request_index++;
64+
}
65+
66+
char log_string[] = "/logs/";
67+
request_index += string_copy(request_buffer + request_index, log_string);
68+
69+
request_buffer[request_index] = CHAR_NUMBERS[decimal];
70+
request_index++;
71+
request_buffer[request_index] = CHAR_NUMBERS[digit];
72+
request_index++;
73+
74+
char get_suffix[] = " HTTP/1.1\n\n{\"username\": \"";
75+
request_index += string_copy(request_buffer + request_index, get_suffix);
76+
77+
// copy username
78+
for(size_t user_index = user_start; user_index < user_end; user_index++){
79+
request_buffer[request_index] = auth_data[user_index];
80+
request_index++;
81+
}
82+
83+
char json_suffix[] = "\"}";
84+
request_index += string_copy(request_buffer + request_index, json_suffix);
85+
86+
struct io_buffer request = {
87+
.ident = server_name,
88+
.ident_len = server_name_end,
89+
.data = request_buffer,
90+
.data_len = request_index,
91+
.key = 0,
92+
};
93+
dandelion_add_output(1, request);
94+
}
95+
96+
return 0;
97+
}
98+
99+
DANDELION_ENTRY(main)

0 commit comments

Comments
 (0)