手撕死锁检测

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>

typedef unsighed long int uint64;

#define MAX 100
//定义类型:线程或者是资源
enum Type{PROCESS, RESOURCE};
//定义源类型
struct source_type{
    uint64 id;
    enum Type type;

    uint64 lock_id;
    int degress;
};
//定义图中的一个顶点
struct vertex{
    struct source_type s;
    struct vertex *next;
};
//定义任务图
struct task_graph{
    struct vertex list[MAX];
    int num;
    
    struct source_type locklist[MAX];
    int lockidx;

    pthread_mutex_t mutex;
};

struct task_graph *tg = NULL;
int path[MAX+1];
int visited[MAX];
int k = 0;
int deadlock = 0;

//创建一个新的顶点
struct vertex *create_vertex(struct source_type type){
    struct vertex *tex = (struct vertex *)mallco(sizeof(struct vertex));

    tex->s = type;
    tex->next = NULL;
    return tex;
}

//在任务图中搜索一个顶点
int search_vertex(struct source_type type){
    int i = 0;
    
    for(i = 0;i < tg->num ;i++){
        if(tg->list[i].s.type == type.type && tg->list[i].s.id == type.id){
            return i;
        }
    }
    return -1;
}
//添加一个顶点到任务图
void add_vertex(struct source_type type){
    if(search_vertex(type) == -1){
        tg->list[tg->num].s = type;
        tg->list[tg->num].next = NULL;
        tg->num ++;
    }
}
//在任务图中添加一条边
int add_edge(struct source_type from, struct source_type to){
    add_vertex(from);
    add_vertex(to);
    
    struct vertex *v = &(tg->list[search_vertex(from)]);
    while(v->next !=NULL){
        v = v->next;
    }
    v->next = create_vertex(to);
}
//验证任务图中是否存在一条边
int verify_edge(struct source_type i, struct source_type j){
    if(tg->num ==0) return 0;
    int idx = search_vertex(i);
    if(idx == -1)return 0;
    
    struct vertex *v = &(tg->list[idx]);
    while(v != NULL){
        if(v->s.id == j.id)return 1;
        v = v->next;
    }
    return 0;
}
//从任务图中删除一条边
int remove_edge(struct source_type from, struct source_type to){
    int idxi = search_vertex(from);
    int idxj = search_vertex(to);

    if(idxi != -1 && idxj != -1){
        struct *v = &tg->list[idxi];
        struct vertex *remove;
        while(v->next !=NULL){
            if(v->s.id == to.id){
                remove = v->next;
                v->next = v->next->next;

                free(remove);
                break;
            }
            v = v->next;    
        }
    }
}

//打印死锁循环
void print_deadlock(void){
    int i = 0;
    
    printf("cycle :");
    for(i = 0;i< k-1;i ++){
        printf("%ld --> ", tg->list[path[i]].s.id);
    }
    printf("%ld\n", tg->list[path[i]].s.id);
}

//深度优先搜索
int DFS(int idx){
    struct vertex *ver = &tg->list[idx];
    if(visited[idx] ==1){
        path[k++] = idx;
        print_deadlock();
        deadlock =1;
        return 0;
    }
    visited[idx] = 1;
    path[k++] = idx;

    while(ver->next != NULL){
        DFS(search_vertex(ver->next->s));
        k --;
        ver = ver->next;
    }
    return 1;
}

//搜索任务图中的循环
int search_for_cycle(int idx){
    struct vertex *ver = &tg->list[idx];
    visited[idx] = 1;
    k = 0;
    path[k++] = idx;

    while(ver->next != NULL){
        int i = 0;
        for(i = 0; i < tg->num; i++){
            if(i == idx)continue;
            visited[i] = 0;
        }
        for(i = 1; i<=MAX; i++){
            path[i] = -1;
        }
        k = 1;
        DFS(search_vertex(ver->next->s));
        ver = ver->next;
    }
}
//搜索锁
int search_lock(uint64 lock){
    int i = 0;
    for(i = 0; i< tg->lockidx; i++){
        if(tg->locklist[i].lock_id = lock){
            return i;
        }
    }
    return -1;
}
//搜索空锁
int search_empty_lock(uint64 lock){
    int i = 0;
    for(i =0; i< tg->lockidx; i++){
        if(tg->locklist[i].lock_id == 0){
            return i;
        }
    }
    return tg->lockidx;
}
//锁之前调用
void lock_before(uint64_t tid, uint64_t lockaddr){
    int idx = 0;
    for(idx = 0; idx < tg->lockidx; idx ++){
        if(tg->locklist[idx].lock_id == lockaddr){
            struct source_type from;
            from.id = tid;
            from.type = PROCESS;
            add_vertex(from);
            
            struct source_type to;
            to.id = tg->locklist[idx].id;
            to.type = PROCESS;
            add_vertex(to);

            tg->locklist[idx].degress ++;

            if(!verify_edge(from,to))add_edge(from, to);
        }
    }
}
//锁之后调用
void lock_after(uint64_t tid, uint64_t lockaddr){
    int idx = 0;
    if(-1 == (idx = search_lock(lockaddr))){
        int eidx = search_empty_lock(lockaddr);
        tg->locklist[eidx].id = tid;
        tg->locklist[eidx].lock_id = lockaddr;

        tg->lockidx ++;
    }else{
        struct source_type from;
		from.id = tid;
		from.type = PROCESS;
		add_vertex(from);

		struct source_type to;
		to.id = tg->locklist[idx].id;
		to.type = PROCESS;
		add_vertex(to);

		
		tg->locklist[idx].degress --;
        if (verify_edge(from, to))remove_edge(from, to);

		tg->locklist[idx].id = tid;

    }
}
//解锁之前调用
void unlock_after(uint64_t tid, uint64_t lockaddr){
	int idx = search_lock(lockaddr);

	if (tg->locklist[idx].degress == 0) {
		tg->locklist[idx].id = 0;
		tg->locklist[idx].lock_id = 0;
	}

}
//检查当前是否有死锁
void check_dead_lock(void){
    int i = 0;

	deadlock = 0;
	for (i = 0;i < tg->num;i ++) {
		if (deadlock == 1) break;
		search_for_cycle(i);
	}

	if (deadlock == 0) {
		printf("no deadlock\n");
	}

}
//定期调用检查死锁

static void *thread_routine(void *args) {

	while (1) {

		sleep(5);
		check_dead_lock();

	}

}

//初始化任务图并启动检查线程
void start_check(void) {

	tg = (struct task_graph*)malloc(sizeof(struct task_graph));
	tg->num = 0;
	tg->lockidx = 0;
	
	pthread_t tid;

	pthread_create(&tid, NULL, thread_routine, NULL);

}

//hook 定义自己的互斥锁
typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *mutex);
pthread_mutex_lock_t pthread_mutex_lock_f = NULL;

typedef int (*pthread_mutex_unlock_t)(pthread_mutex_t *mutex);
pthread_mutex_unlock_t pthread_mutex_unlock_f = NULL;


// implement
int pthread_mutex_lock(pthread_mutex_t *mutex) {

	
	pthread_t selfid = pthread_self();
	
	lock_before((uint64_t)selfid, (uint64_t)mutex);
	
	pthread_mutex_lock_f(mutex);

	lock_after((uint64_t)selfid, (uint64_t)mutex);

	
}

int pthread_mutex_unlock(pthread_mutex_t *mutex) {

	pthread_mutex_unlock_f(mutex);

	pthread_t selfid = pthread_self();
	unlock_after((uint64_t)selfid, (uint64_t)mutex);
	
}

// init
void init_hook(void) {

	if (!pthread_mutex_lock_f)
		pthread_mutex_lock_f = dlsym(RTLD_NEXT, "pthread_mutex_lock");

	if (!pthread_mutex_unlock_f)
		pthread_mutex_unlock_f = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值