diff --git a/Makefile b/Makefile
index a6b2736211a854ad0e68d59709a4c5fa50416569..f18490c7ed27dedcde8438fd98d2066753de74ef 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 OPTION=-m32
 
-all: display_stack try_mul pingpong
+all: display_stack try_mul pingpong pingpongpang
 
 display_stack : display_stack.o
 	gcc $(OPTION) -o $@ $^
@@ -11,8 +11,11 @@ try_mul : try.o try_mul.o
 pingpong : try.o pingpong.o
 	gcc $(OPTION) -o $@ $^
 
+pingpongpang : try.o pingpongpang.o
+	gcc $(OPTION) -o $@ $^
+
 %.o:%.c
 	gcc $(OPTION) -c $<
 
 clean:
-	rm -f *.o *.s display_stack try_mul pingpong
+	rm -f *.o *.s display_stack try_mul pingpong pingpongpang
diff --git a/pingpongpang.c b/pingpongpang.c
new file mode 100644
index 0000000000000000000000000000000000000000..980f391f18e3e7d4051282f1b4a70812e8b1b93d
--- /dev/null
+++ b/pingpongpang.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "try.h"
+
+#define STACK 16384
+
+void f_ping(void *args);
+void f_pong(void *args);
+void f_pang(void *args);
+
+int main(int argc, char *argv[])
+{
+    ctx_t *pang_ctx = create_ctx(STACK, f_pang, NULL);
+    ctx_t *pong_ctx = create_ctx(STACK, f_pong, NULL);
+    ctx_t *ping_ctx = create_ctx(STACK, f_ping, NULL);
+    printf("Begin \n");
+    yield();
+    printf("End \n");
+    exit(EXIT_SUCCESS);
+}
+
+void f_ping(void *args)
+{
+    printf("A");
+    yield();
+    printf("B");
+    yield();
+    printf("C");
+    yield();
+}
+
+void f_pong(void *args)
+{
+    printf("1");
+    yield();
+    printf("2");
+    yield();
+}
+
+void f_pang(void *args)
+{
+    printf("(");
+    yield();
+    printf(":");
+    yield();
+    printf(")");
+    yield();
+}
diff --git a/try.c b/try.c
index ea0bbaff473f58cb26af3cf5d664d2d49bbc449a..46c18250f1cc5115921979540562fe5c9c03290c 100644
--- a/try.c
+++ b/try.c
@@ -2,6 +2,9 @@
 #include <assert.h>
 #include "try.h"
 
+static ctx_t *current_ctx = NULL;
+static ctx_t *ring_ctx = NULL;
+
 int try(ctx_t *pctx, func_t *f, int arg)
 {
     asm("movl %%esp, %0"
@@ -38,7 +41,6 @@ int init_ctx(ctx_t *pctx, int stack_size, funct_t f, void *args)
     pctx->status = CTX_INIT;
 }
 
-static ctx_t *current_ctx = NULL;
 void switch_to_ctx(ctx_t *pctx)
 {
     assert(pctx->status != CTX_END);
@@ -67,5 +69,33 @@ void start_ctx()
     current_ctx->status = CTX_EXEC;
     current_ctx->f(current_ctx->args);
     current_ctx->status = CTX_END;
-    free(current_ctx->stack);
+    yield();
+}
+
+ctx_t *create_ctx(int stack_size, funct_t f, void *args)
+{
+    ctx_t *new_ctx = malloc(sizeof(ctx_t));
+
+    if (ring_ctx == NULL)
+    {
+        new_ctx->next_ctx = new_ctx;
+        ring_ctx = new_ctx;
+    }
+    else
+    {
+        new_ctx->next_ctx = ring_ctx->next_ctx;
+        ring_ctx->next_ctx = new_ctx;
+    }
+
+    init_ctx(new_ctx, stack_size, f, args);
+    return new_ctx;
+}
+
+void yield()
+{
+    assert(ring_ctx != NULL || current_ctx != NULL);
+    if (current_ctx == NULL)
+        switch_to_ctx(ring_ctx->next_ctx);
+    else
+        switch_to_ctx(current_ctx->next_ctx);
 }
\ No newline at end of file
diff --git a/try.h b/try.h
index 27d015a6c77d518810d5d941d64ee08fdcabca3f..b62722caaa89b943f04a282825b9adda2ba4599f 100644
--- a/try.h
+++ b/try.h
@@ -11,7 +11,7 @@ typedef enum
     CTX_END
 } ctx_status_t;
 
-typedef struct
+typedef struct ctx_s
 {
     void *esp;
     void *ebp;
@@ -19,6 +19,7 @@ typedef struct
     funct_t *f;
     void *args;
     ctx_status_t status;
+    struct ctx_s *next_ctx;
 } ctx_t;
 
 int try(ctx_t *, func_t *, int);
@@ -31,4 +32,8 @@ void switch_to_ctx(ctx_t *);
 
 void start_ctx();
 
+ctx_t *create_ctx(int, funct_t, void *);
+
+void yield();
+
 #endif // TRY