diff --git a/serie4/ex1/ex1.md b/serie4/ex1/ex1.md
new file mode 100644
index 0000000000000000000000000000000000000000..e072aea6ff6efe342fbd0c1475af08dc7f947293
--- /dev/null
+++ b/serie4/ex1/ex1.md
@@ -0,0 +1,34 @@
+# Exercice 1
+
+## Question 
+
+Est-ce que l'algorithme ci-dessous garanti l'exclusion mutuelle sur un monoprocesseur (exclusion
+mutuelle, progression, attente bornée) entre les threads T0 et T1 ? Si ce n’est pas la cas, justifiez
+votre réponse en décrivant une séquence possible d’opérations qui prouve le contraire.
+
+```c
+bool inside[2] = {false, false};
+
+// id is the thread number (0 or 1)
+void prelude(int id) {
+    while (inside[1 - id]) {}
+    inside[id] = true;
+}
+
+void postlude(int id) {
+    inside[id] = false;
+}
+```
+
+## Réponse
+
+Vu que nous sommes sur une architecture monoprocesseur, cela signifie que le
+code ne pourra pas s'exécuter de manière parallèle, il n'y aura que des
+changements de contexte.
+
+Si l'on part du principe que T0 rentre dans la fonction `prelude`, exécute la
+ligne correspondante à la boucle `while (false)` qu'à la suite de cela, il y'a
+un changement de contexte dans lequel T1 exécute les deux lignes de la fonction
+`prelude` et que finalement T0 reprend l'exécution, à la fin on aboutira avec
+les deux variables du tableau `inside` à `true` ce qui implique le fait que cet
+algorithme ne garanti pas l'exclusion mutuelle car les deux variables sont à `true`.
diff --git a/serie4/ex2/.gitignore b/serie4/ex2/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b6de771d2fff3a218dbc1b3de5b6b6cc1dc54e08
--- /dev/null
+++ b/serie4/ex2/.gitignore
@@ -0,0 +1,2 @@
+*.o
+prog
diff --git a/serie4/ex2/Makefile b/serie4/ex2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f702d8a6c8186500ac1ba446cff2df5a7e11690f
--- /dev/null
+++ b/serie4/ex2/Makefile
@@ -0,0 +1,26 @@
+CC := clang
+CFLAGS := -g -pedantic -Wall -Wextra -std=c11
+LDFLAGS := -fsanitize=address -fsanitize=leak -fsanitize=undefined -lm -lpthread
+TARGET := prog
+
+all: $(TARGET)
+
+$(TARGET): prog.o
+	@printf "=================== Building executable ===================\n"
+	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
+	@printf "\n"
+
+%.o: %.c
+	@printf "================== Building object files ==================\n"
+	$(CC) $(CFLAGS) -c $<
+	@printf "\n"
+
+
+.PHONY: clean
+
+clean:
+	rm -f *.o $(TARGET)
+
+.PHONY: rebuild
+	
+rebuild: clean all
diff --git a/serie4/ex2/prog.c b/serie4/ex2/prog.c
new file mode 100644
index 0000000000000000000000000000000000000000..0571354d24c52ef6a7113b8ffbd4ee58db3bc849
--- /dev/null
+++ b/serie4/ex2/prog.c
@@ -0,0 +1,53 @@
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NB_THREADS 2
+#define MAX_INCREMENT 10000
+
+int lock;
+int counter;
+
+void init_lock(int *lock_ptr) { __sync_val_compare_and_swap(lock_ptr, 0, 0); }
+
+void acquire_lock(int *lock_ptr) {
+    __sync_val_compare_and_swap(lock_ptr, *lock_ptr, 1);
+}
+
+void release_lock(int *lock_ptr) {
+    __sync_val_compare_and_swap(lock_ptr, *lock_ptr, 0);
+}
+
+void *routine(void *arg) {
+    int *counter = (int *)arg;
+    acquire_lock(&lock);
+    for (int i = 0; i < MAX_INCREMENT; i++) {
+        (*counter)++;
+    }
+    release_lock(&lock);
+
+    return NULL;
+}
+
+int main(void) {
+    pthread_t threads[NB_THREADS];
+
+    init_lock(&lock);
+
+    for (int i = 0; i < NB_THREADS; i++) {
+        if (pthread_create(&threads[i], NULL, routine, &counter) == -1) {
+            perror("pthread_create");
+        }
+    }
+
+    for (int i = 0; i < NB_THREADS; i++) {
+        if (pthread_join(threads[i], NULL)) {
+            perror("pthread_join");
+        }
+    }
+
+    fprintf(stdout, "Value of counter = %d\n", counter);
+
+    return EXIT_SUCCESS;
+}