Skip to content

Commit

Permalink
arg/parallel-graph: Update skeleton implementation
Browse files Browse the repository at this point in the history
Synchronize skeleton implementation with the official soluion. The
official solution is a redesign of the thread pool, together with the
use of a generic list implementation (inspired from the Linux kernel).

Signed-off-by: Razvan Deaconescu <[email protected]>
  • Loading branch information
razvand committed Nov 20, 2023
1 parent d174e98 commit b8de82b
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 208 deletions.
40 changes: 19 additions & 21 deletions content/assignments/parallel-graph/src/Makefile
Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
BUILD_DIR := build
CC := gcc
CFLAGS := -c -Wall -g
LD := ld
LDFLAGS :=
LDLIBS := -lpthread

SERIAL_SRCS := serial.c os_graph.c
PARALLEL_SRCS:= parallel.c os_graph.c os_list.c os_threadpool.c
SERIAL_OBJS := $(patsubst $(SRC)/%.c,$(BUILD_DIR)/%.o,$(SERIAL_SRCS))
PARALLEL_OBJS := $(patsubst $(SRC)/%.c,$(BUILD_DIR)/%.o,$(PARALLEL_SRCS))
UTILS_PATH ?= ../utils
CPPFLAGS := -I$(UTILS_PATH)
CFLAGS := -Wall -Wextra
# Remove the line below to disable debugging support.
CFLAGS += -g -O0
PARALLEL_LDLIBS := -lpthread

SERIAL_SRCS := serial.c os_graph.c $(UTILS_PATH)/log/log.c
PARALLEL_SRCS:= parallel.c os_graph.c os_threadpool.c $(UTILS_PATH)/log/log.c
SERIAL_OBJS := $(patsubst %.c,%.o,$(SERIAL_SRCS))
PARALLEL_OBJS := $(patsubst %.c,%.o,$(PARALLEL_SRCS))

.PHONY: all pack clean always

all: serial parallel

always:
mkdir -p build

serial: always $(SERIAL_OBJS)
$(CC) $(LDFLAGS) -o serial $(SERIAL_OBJS)
serial: $(SERIAL_OBJS)
$(CC) -o $@ $^

parallel: always $(PARALLEL_OBJS)
$(CC) $(LDFLAGS) -o parallel $(PARALLEL_OBJS) $(LDLIBS)
parallel: $(PARALLEL_OBJS)
$(CC) -o $@ $^ $(PARALLEL_LDLIBS)

$(BUILD_DIR)/%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
$(UTILS_PATH)/log/log.o: $(UTILS_PATH)/log/log.c $(UTILS_PATH)/log/log.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

pack: clean
-rm -f ../src.zip
zip -r ../src.zip *

clean:
-rm -f ../src.zip
-rm -rf build
-rm -f $(SERIAL_OBJS) $(PARALLEL_OBJS)
-rm -f serial parallel
-rm -f *~
53 changes: 34 additions & 19 deletions content/assignments/parallel-graph/src/os_graph.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
// SPDX-License-Identifier: BSD-3-Clause

#include "os_graph.h"
#include <stdio.h>
#include <stdlib.h>

#include "os_graph.h"
#include "log/log.h"
#include "utils.h"

/* Node functions */
os_node_t *os_create_node(unsigned int id, int info)
{
os_node_t *node;

node = calloc(1, sizeof(*node));
node = malloc(sizeof(*node));
DIE(node == NULL, "mallloc");

node->id = id;
node->info = info;
node->num_neighbours = 0;
node->neighbours = NULL;

return node;
}
Expand All @@ -21,58 +27,69 @@ os_node_t *os_create_node(unsigned int id, int info)
os_graph_t *create_graph_from_data(unsigned int num_nodes, unsigned int num_edges,
int *values, os_edge_t *edges)
{
int i, isrc, idst;
os_graph_t *graph;

graph = calloc(1, sizeof(*graph));
graph = malloc(sizeof(*graph));
DIE(graph == NULL, "mallloc");

graph->num_nodes = num_nodes;
graph->num_edges = num_edges;

graph->nodes = calloc(num_nodes, sizeof(os_node_t *));
graph->nodes = malloc(num_nodes * sizeof(os_node_t *));
DIE(graph->nodes == NULL, "malloc");

for (i = 0; i < num_nodes; ++i) {
for (unsigned int i = 0; i < graph->num_nodes; i++) {
graph->nodes[i] = os_create_node(i, values[i]);
graph->nodes[i]->neighbours = calloc(num_nodes, sizeof(unsigned int));
graph->nodes[i]->neighbours = malloc(graph->num_nodes * sizeof(unsigned int));
DIE(graph->nodes[i]->neighbours == NULL, "malloc");
graph->nodes[i]->num_neighbours = 0;
}

for (i = 0; i < num_edges; ++i) {
isrc = edges[i].src; idst = edges[i].dst;
for (unsigned int i = 0; i < graph->num_edges; i++) {
unsigned int isrc, idst;

isrc = edges[i].src;
idst = edges[i].dst;
graph->nodes[isrc]->neighbours[graph->nodes[isrc]->num_neighbours++] = idst;
graph->nodes[idst]->neighbours[graph->nodes[idst]->num_neighbours++] = isrc;
}

graph->visited = calloc(graph->num_nodes, sizeof(*graph->visited));
graph->visited = malloc(graph->num_nodes * sizeof(*graph->visited));
DIE(graph->visited == NULL, "malloc");

for (unsigned int i = 0; i < graph->num_nodes; i++)
graph->visited[i] = NOT_VISITED;

return graph;
}

os_graph_t *create_graph_from_file(FILE *file)
{
unsigned int num_nodes, num_edges;
int i;
unsigned int i;
int *nodes;
os_edge_t *edges;
os_graph_t *graph = NULL;

if (fscanf(file, "%d %d", &num_nodes, &num_edges) == 0) {
fprintf(stderr, "[ERROR] Can't read from file\n");
log_error("Can't read from file");
goto out;
}

nodes = malloc(num_nodes * sizeof(int));
for (i = 0; i < num_nodes; ++i) {
DIE(nodes == NULL, "malloc");
for (i = 0; i < num_nodes; i++) {
if (fscanf(file, "%d", &nodes[i]) == 0) {
fprintf(stderr, "[ERROR] Can't read from file\n");
log_error("Can't read from file");
goto free_nodes;
}
}

edges = malloc(num_edges * sizeof(os_edge_t));
DIE(edges == NULL, "malloc");
for (i = 0; i < num_edges; ++i) {
if (fscanf(file, "%d %d", &edges[i].src, &edges[i].dst) == 0) {
fprintf(stderr, "[ERROR] Can't read from file\n");
log_error("Can't read from file");
goto free_edges;
}
}
Expand All @@ -89,11 +106,9 @@ os_graph_t *create_graph_from_file(FILE *file)

void print_graph(os_graph_t *graph)
{
int i, j;

for (i = 0; i < graph->num_nodes; ++i) {
for (unsigned int i = 0; i < graph->num_nodes; i++) {
printf("[%d]: ", i);
for (j = 0; j < graph->nodes[i]->num_neighbours; ++j)
for (unsigned int j = 0; j < graph->nodes[i]->num_neighbours; j++)
printf("%d ", graph->nodes[i]->neighbours[j]);
printf("\n");
}
Expand Down
10 changes: 7 additions & 3 deletions content/assignments/parallel-graph/src/os_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

typedef struct os_node_t {
unsigned int id;
signed int info;
int info;

unsigned int num_neighbours;
unsigned int *neighbours;
Expand All @@ -18,11 +18,15 @@ typedef struct os_graph_t {
unsigned int num_edges;

os_node_t **nodes;
unsigned int *visited;
enum {
NOT_VISITED = 0,
PROCESSING = 1,
DONE = 2
} *visited;
} os_graph_t;

typedef struct os_edge_t {
int src, dst;
unsigned int src, dst;
} os_edge_t;

os_node_t *os_create_node(unsigned int id, int info);
Expand Down
63 changes: 52 additions & 11 deletions content/assignments/parallel-graph/src/os_list.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,64 @@
/* SPDX-License-Identifier: BSD-3-Clause */

/*
* Heavily inspired for Linux kernel code:
* https://github.com/torvalds/linux/blob/master/include/linux/list.h
*/

#ifndef __OS_LIST_H__
#define __OS_LIST_H__ 1

#include <pthread.h>
#include <stddef.h>

typedef struct os_list_node_t {
void *info;
struct os_list_node_t *next;
struct os_list_node_t *prev, *next;
} os_list_node_t;

typedef struct {
struct os_list_node_t *first;
struct os_list_node_t *last;
pthread_mutex_t lock;
} os_queue_t;
static inline void list_init(os_list_node_t *head)
{
head->prev = head;
head->next = head;
}

static inline void list_add(os_list_node_t *head, os_list_node_t *node)
{
node->next = head->next;
node->prev = head;
head->next->prev = node;
head->next = node;
}

static inline void list_add_tail(os_list_node_t *head, os_list_node_t *node)
{
node->prev = head->prev;
node->next = head;
head->prev->next = node;
head->prev = node;
}

static inline void list_del(os_list_node_t *node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
node->next = node;
node->prev = node;
}

static inline int list_empty(os_list_node_t *head)
{
return (head->next == head);
}

#define list_entry(ptr, type, member) ({ \
void *tmp = (void *)(ptr); \
(type *) (tmp - offsetof(type, member)); \
})

#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)

os_queue_t *queue_create(void);
void queue_add(os_queue_t *queue, void *info);
os_list_node_t *queue_get(os_queue_t *queue);
#define list_for_each_safe(pos, tmp, head) \
for (pos = (head)->next, tmp = pos->next; pos != (head); \
pos = tmp, tmp = pos->next)

#endif
Loading

0 comments on commit b8de82b

Please sign in to comment.