···11# tsched
2233-This project is the second assignment for CCOM4017.
33+This project is the second assignment for CCOM-4017.
4455-I am using a sockets library I developed myself on:
55+I am using a sockets library I developed mysel. For more information on how the
66+sockets library was developed, feel free to visit the repo:
67- https://git.gay/sona/enchufe
7899+For threads, I am using a builtin library called `threads.h`. This library is
1010+documented on [cppreference.com](https://cppreference.com) as:
1111+- https://en.cppreference.com/w/c/header/threads.html
1212+1313+From this library I used the functionality provided to create the threads and
1414+the mutex that they define.
1515+816# Running
9171010-You can simply execute:
1818+## Cluster
11191220```sh
1313-make run
2121+make cluster.py
1422```
15231616-This will run the cluster on address `127.0.0.1` on port `42069` and connect the
1717-embedded device to it.
1818-1919-If you prefer to run each separately then you can run the program like in the
2020-following two sections.
2121-2222-## Cluster
2424+This will simply run the cluster on the server's loopback `127.0.0.1` and on
2525+port `42069`. If youu want to supply your own server and port, use:
23262427```sh
2528make cluster.py ADDRESS=<server address> PORT=<server port>
2629```
27302831where `<server address>` is the IP address of the cluster, and `<server port>`
2929-is the port number of the cluster.
3232+is the port number of the cluster. Remember that you must put the words
3333+"`ADDRESS`" and "`PORT`" before the `<server address>` and `<server port>`. If
3434+you don't `make` will not detect that you passed those arguments to the
3535+executable.
30363137## Embedded device
32383333-Example of how to run the embedded device:
3939+This is the same as the cluster. The default server and port are the loopback
4040+and `42069` respectively, and supplying the parameters for `ADDRESS` and `PORT`
4141+will let make know on which server and port you want to run it.
34423543```sh
3644make edevice.py ADDRESS=<server address> PORT=<server port>
···3947where `<server address>` is the IP address of the cluster, and `<server port>`
4048is the port number of the cluster.
41494242-Example of how to run the cluster:
5050+# Building
5151+5252+If you just want to build the files, run:
5353+5454+```sh
5555+make .build/edevice
5656+```
5757+5858+To build the embedded device and run:
5959+6060+```sh
6161+make .build/cluster
6262+```
43636464+To build the cluster. From these two executables, you can then run the programs
6565+like,
6666+```sh
6767+./.build/cluster <server address> <server port>
6868+./.build/edevice <server address> <server port>
6969+```
7070+7171+# Contributions
7272+7373+I would like to thank Gabriel Romero and Anasofia Colon while developing this
7474+project. Without them, this project would have been impossible.
+3
src/cluster.c
···1919bool client_closed = false;
202021212222+// The consumer.
2223int consume(void*args) {
2324 // Turns the strange looking thing thrd_current() into a smaller number.
2425 size_t tid = ((thrd_current() & 0xFFFF) >> 12) % 12;
25262627 log(INFO, "Consumer %zu started.\n", tid);
27282929+ // Get client from argument.
2830 exists(args);
2931 Enchufe cliente = *(Enchufe*)args;
3032···6163 return thrd_success;
6264}
63656666+// The producer.
6467int produce(void* args) {
6568 exists(args);
6669 Enchufe cliente = *(Enchufe*)args;
+20-4
src/edevice.c
···1111int main(int argc, char** argv) {
1212 assert(argc == 3 && "You must provide three arguments.");
13131414+ // Create the socket
1415 IPv4 ip = parse_address(argv[1]);
1516 Port port = (Port)atoi(argv[2]);
1617 log(INFO, "Connecting to: %d.%d.%d.%d on port: %d", ip.bytes[0], ip.bytes[1], ip.bytes[2], ip.bytes[3], port);
···1819 Enchufe enchufe = enchufa(ip, port);
1920 conecta(enchufe);
20212222+ /* run the command
2323+ * here I used `ps auxww -Aeo args` in order to use the entire string used
2424+ * by `ps`.
2525+ */
2126 FILE* fp = popen("ps auxww -Aeo args", "r");
2227 exists(fp);
23282929+ // Initialize random seed generator.
2430 srand((uint32_t)time(NULL));
3131+2532 char program[BUF_LEN];
2626- size_t counter = 0;
2727- while (fgets(program, BUF_LEN, fp)) {
3333+ for (size_t counter = 0; fgets(program, BUF_LEN, fp); ++counter) {
3434+ /* the first two lines of that `ps` command are the headers for the
3535+ * output, not actual programs.
3636+ */
2837 if (counter <3 ) {
2938 ++counter;
3039 continue;
···3443 size_t len = safe_strlen(program, BUF_LEN) - 1;
3544 program[len] = '\0';
36454646+ // Create the process that will be sent
3747 Proc proc = {
3848 .time = (Time)rand() % 5,
3949 .program = {
···4252 },
4353 };
44545555+ // Send the process.
4556 log(INFO, "Sent program: %s with time %d.\n", proc.program.buf, proc.time);
4646-4757 Buffer in_buf = serialize(proc);
4858 zumba(enchufe, in_buf);
49596060+ /* Clear the buffer for the program and free the memory associated to
6161+ * what was just sent.
6262+ */
5063 memset(program, 0, BUF_LEN);
5164 free(in_buf.buf);
5252- ++counter;
53656666+ // Create new buffer to receive output from cluster.
5467 Byte buf[BUF_LEN] = {0};
5568 Buffer out_buf = {
5669 .buf = buf,
5770 .len = BUF_LEN,
5871 };
7272+ // Receive message from cluster.
5973 size_t msg_len = recibe(enchufe, out_buf);
6074 assert(safe_strlen((char*)out_buf.buf, BUF_LEN) == msg_len);
6175 log(INFO, "Received: %s.\n", (char*)out_buf.buf);
6276 }
63777878+ // Let the user know that the program is done.
6479 log(INFO, "Done.\n");
65808181+ // Close socket.
6682 desenchufa(enchufe);
67836884 return 0;