Created
November 28, 2016 20:26
-
-
Save ragavvenkatesan/c770d2b389da0d5c61f00ccbae0993d7 to your computer and use it in GitHub Desktop.
Killing Threads
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Refer https://github.com/ragavvenkatesan/client-server-udp-protocol repository for include files. | |
#define VERBOSE 1 | |
#include<stdio.h> | |
#include "sem.h" | |
void thread () | |
{ | |
int i = 0; | |
for (i = 0; i< 10; i++) | |
{ | |
printf("thread %d says %d \n", Curr_Thread->id, i); | |
yield(); | |
} | |
thread_exit(); // this is in threads.h at the repository mentioned above and in this gist. | |
// gist would not let me merge this with my repo... so Sorry. | |
} | |
void main() | |
{ | |
int i; | |
NewQueue(&ReadyQ); | |
start_thread(thread); | |
start_thread(thread); | |
start_thread(thread); | |
run(); // main gets dumped here. | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef THREADS_H | |
#define THREADS_H | |
#include "q.h" | |
#include "tcb.h" | |
int exitCounter=0; | |
struct TCB_t *ReadyQ; | |
struct TCB_t *Curr_Thread; | |
struct TCB_t *exit_thread; | |
int threadCounter = 0; | |
#ifndef VERBOSE | |
#define VERBOSE 2 | |
#endif | |
void start_thread(void (*function)(void)) | |
{ | |
int *stack; | |
stack=(int *) malloc(8192); | |
threadCounter ++; | |
if(VERBOSE >= 1) | |
{ | |
printf("Starting a new thread %d .. \n", threadCounter); | |
} | |
struct TCB_t *tcb; | |
tcb=NewItem(); | |
init_TCB(tcb,function,stack,8192); | |
tcb->id = threadCounter; | |
AddQueue(&ReadyQ,tcb); | |
} | |
void exit_function() | |
{ | |
printf("All threads are killed. Toodles \n"); | |
exit(0); | |
} | |
void arm_exit() | |
{ | |
start_thread(exit_function); // add a new thread to the ReadyQ that will load a function which says | |
// 'toodles' and leaves. | |
} | |
// will kill the current thread | |
void thread_exit() | |
{ | |
printf("Thread %d is exiting\n",Curr_Thread->id); | |
threadCounter --; | |
if(threadCounter == 0) // If you are the last thread in the readyQ, load a dummy exit thread to elegantly | |
// finish the program instead of seg-faulting. | |
{ | |
arm_exit(); | |
} | |
Curr_Thread = DelQueue(&ReadyQ); | |
ucontext_t dump; // get a place to store the dump context, for faking | |
getcontext(&dump); // magic sauce :) | |
swapcontext(&dump, &(Curr_Thread->context)); // start the next thread on readyQ | |
} | |
void run() | |
{ // real code | |
if(VERBOSE >= 1) | |
{ | |
printf("User scheduler is taking over .. \n"); | |
} | |
if (VERBOSE >=2) | |
{ | |
printf("Ready Queue:"); | |
PrintQueue(&ReadyQ); | |
} | |
Curr_Thread = DelQueue(&ReadyQ); | |
ucontext_t parent; // get a place to store the main context, for faking | |
getcontext(&parent); // magic sauce | |
swapcontext(&parent, &(Curr_Thread->context)); // start the first thread | |
// Comes here only when main in reloaded, which never happes | |
} | |
void yield() | |
{ | |
if (VERBOSE >=2) | |
{ | |
printf("Context switch .. \n"); | |
printf("Ready Queue Before:"); | |
PrintQueue(&ReadyQ); | |
} | |
if(VERBOSE >= 2) | |
{ | |
} | |
struct TCB_t *Prev_Thread; | |
AddQueue(&ReadyQ, Curr_Thread); | |
Prev_Thread = Curr_Thread; | |
Curr_Thread = DelQueue(&ReadyQ); | |
swapcontext(&(Prev_Thread->context),&(Curr_Thread->context)); | |
if (VERBOSE >=2) | |
{ | |
printf("Ready Queue After:"); | |
PrintQueue(&ReadyQ); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a demonstration of thread killing using the semaphore structures in the Git: https://github.com/ragavvenkatesan/client-server-udp-protocol
This was a demonstration on some forum.