Skip to content

Instantly share code, notes, and snippets.

@ragavvenkatesan
Created November 28, 2016 20:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ragavvenkatesan/c770d2b389da0d5c61f00ccbae0993d7 to your computer and use it in GitHub Desktop.
Save ragavvenkatesan/c770d2b389da0d5c61f00ccbae0993d7 to your computer and use it in GitHub Desktop.
Killing Threads
// 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.
}
#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
@ragavvenkatesan
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment