mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-09-24 14:13:54 +08:00
gcc优化和如何使用-O2编译内核...
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
target=mutex_bug sem_bug bug \
|
||||
sem_test check_lock \
|
||||
futex_test futex_bug
|
||||
|
||||
|
||||
all:$(target)
|
||||
|
||||
mutex_bug:lock_bug.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread -DMUTEX
|
||||
@echo "mutex lock..."
|
||||
|
||||
sem_bug:lock_bug.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread -DSEM
|
||||
@echo "mutex lock..."
|
||||
|
||||
bug:lock_bug.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread
|
||||
@echo "none lock..."
|
||||
|
||||
sem_test:sem_test.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread
|
||||
@echo "bug use mutex..."
|
||||
|
||||
|
||||
check_lock:check_lock.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread
|
||||
@echo "check lock..."
|
||||
|
||||
|
||||
futex_bug:futex_bug.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread
|
||||
@echo "bug use futex..."
|
||||
|
||||
|
||||
futex_test:futex_test.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread
|
||||
@echo "futex workthread sendthread..."
|
||||
|
||||
|
||||
bind:bind.c
|
||||
$(CC) $^ -o $@ $(LDFLAGS) -lpthread
|
||||
@echo "set cpu affine..."
|
||||
#%.o : %.c
|
||||
# $(CC) -c $^ -o $@ $(CFLAGS) $(DEFINES)
|
||||
#
|
||||
#%.o : %.cpp
|
||||
# $(CXX) -c $^ -o $@ $(CFLAGS) $(DEFINES)
|
||||
|
||||
clean :
|
||||
rm -rf *.o
|
||||
rm -rf $(target)
|
||||
@@ -0,0 +1,64 @@
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
#include<sys/types.h>
|
||||
#include<sys/sysinfo.h>
|
||||
#include<unistd.h>
|
||||
|
||||
#define __USE_GNU
|
||||
#include<sched.h>
|
||||
#include<ctype.h>
|
||||
#include<string.h>
|
||||
#include<pthread.h>
|
||||
#define THREAD_MAX_NUM 100 //1个CPU内的最多进程数
|
||||
|
||||
int num=0; //cpu中核数
|
||||
void* threadFun(void* arg) //arg 传递线程标号(自己定义)
|
||||
{
|
||||
cpu_set_t mask; //CPU核的集合
|
||||
cpu_set_t get; //获取在集合中的CPU
|
||||
int *a = (int *)arg;
|
||||
printf("the a is:%d\n",*a); //显示是第几个线程
|
||||
CPU_ZERO(&mask); //置空
|
||||
CPU_SET(*a,&mask); //设置亲和力值
|
||||
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
|
||||
{
|
||||
printf("warning: could not set CPU affinity, continuing...\n");
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
CPU_ZERO(&get);
|
||||
if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力
|
||||
{
|
||||
printf("warning: cound not get thread affinity, continuing...\n");
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力
|
||||
{
|
||||
printf("this thread %d is running processor : %d\n", i,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
num = sysconf(_SC_NPROCESSORS_CONF); //获取核数
|
||||
pthread_t thread[THREAD_MAX_NUM];
|
||||
printf("system has %i processor(s). \n", num);
|
||||
int tid[THREAD_MAX_NUM];
|
||||
int i;
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
tid[i] = i; //每个线程必须有个tid[i]
|
||||
pthread_create(&thread[0],NULL,threadFun,(void*)&tid[i]);
|
||||
}
|
||||
for(i=0; i< num; i++)
|
||||
{
|
||||
pthread_join(thread[i],NULL);//等待所有的线程结束,线程为死循环所以CTRL+C结束
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,261 @@
|
||||
// http://blog.csdn.net/bgylde/article/details/53096435
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MAX_COUNT 64
|
||||
|
||||
typedef struct tagMute
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
char file[128];
|
||||
int line;
|
||||
int mute_status;
|
||||
struct tagPLAYER * tag_player;
|
||||
} T_MUTE;
|
||||
|
||||
typedef struct tagPLAYER
|
||||
{
|
||||
T_MUTE *player_mux;
|
||||
}T_PLAYER;
|
||||
|
||||
typedef struct tagLIST
|
||||
{
|
||||
int list_count;
|
||||
T_MUTE *list[MAX_COUNT];
|
||||
}T_LIST;
|
||||
|
||||
typedef struct tagARG
|
||||
{
|
||||
|
||||
int shareA, shareB;
|
||||
int count;
|
||||
T_PLAYER *player_A, *player_B;
|
||||
}T_ARG;
|
||||
|
||||
T_LIST *list;
|
||||
|
||||
#define PLAYER_MUXTEX_INIT(x) do {\
|
||||
T_PLAYER *player = (T_PLAYER *)x;\
|
||||
pthread_mutex_init(&(player->player_mux->mutex), NULL);\
|
||||
memset(player->player_mux->file, 0, sizeof(player->player_mux->file));\
|
||||
player->player_mux->line = 0;\
|
||||
player->player_mux->mute_status = 0;\
|
||||
player->player_mux->tag_player = player;\
|
||||
list->list[list->list_count++] = player->player_mux;\
|
||||
}while(0)
|
||||
|
||||
#define PLAYER_MUXTEX_LOCK(x) do {\
|
||||
T_PLAYER *player = (T_PLAYER *)x;\
|
||||
pthread_mutex_lock(&(player->player_mux->mutex));\
|
||||
strncpy(player->player_mux->file, __FILE__, sizeof(player->player_mux->file));\
|
||||
player->player_mux->line = __LINE__;\
|
||||
player->player_mux->mute_status = 1;\
|
||||
}while (0)
|
||||
|
||||
#define PLAYER_MUXTEX_UNLOCK(x) do {\
|
||||
T_PLAYER *player = (T_PLAYER *)x;\
|
||||
player->player_mux->mute_status = 0;\
|
||||
pthread_mutex_unlock(&player->player_mux->mutex);\
|
||||
}while(0)
|
||||
|
||||
#define PLAYER_MUXTEX_DESTROY do {\
|
||||
while(list->list_count){\
|
||||
pthread_mutex_destroy(&list->list[list->list_count-1]->mutex);\
|
||||
free(list->list[list->list_count-1]);\
|
||||
list->list_count--;\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
void handle_dead_lock(void)
|
||||
{
|
||||
int index;
|
||||
flag:
|
||||
printf("Please input unlock index: ");
|
||||
scanf("%d", &index);
|
||||
|
||||
if((index >= 0) &&(index < list->list_count))
|
||||
{
|
||||
PLAYER_MUXTEX_UNLOCK(list->list[index]->tag_player);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Input error!\n");
|
||||
goto flag;
|
||||
}
|
||||
}
|
||||
|
||||
void *loop_detect_deadlock_thread(void *arg)
|
||||
{
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
|
||||
|
||||
T_ARG *argDetect = (T_ARG *)arg;
|
||||
int i = 0;
|
||||
while(1)
|
||||
{
|
||||
T_MUTE *mutex = list->list[i];
|
||||
|
||||
pthread_mutex_lock(&mutex->mutex);
|
||||
argDetect->count ++;
|
||||
pthread_mutex_unlock(&mutex->mutex);
|
||||
|
||||
|
||||
i = (++i) % list->list_count;
|
||||
pthread_testcancel();
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void *loop_detect_count_thread(void *arg)
|
||||
{
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
|
||||
|
||||
T_ARG *argCount = (T_ARG *)arg;
|
||||
do
|
||||
{
|
||||
int temp = argCount->count;
|
||||
sleep(5);
|
||||
if(temp == argCount->count)
|
||||
{
|
||||
printf("dead lock!\n");
|
||||
int i = 0;
|
||||
for(i = 0; i < list->list_count; i++)
|
||||
{
|
||||
if(list->list[i]->mute_status)
|
||||
{
|
||||
printf("%d\tlock at %s:%d\n",i, list->list[i]->file, list->list[i]->line);
|
||||
}
|
||||
}
|
||||
handle_dead_lock();
|
||||
}
|
||||
}while(1);
|
||||
}
|
||||
|
||||
void * thread_fun_A(void * arg)
|
||||
{
|
||||
T_ARG *argA = (T_ARG *)arg;
|
||||
PLAYER_MUXTEX_LOCK(argA->player_A);
|
||||
printf("threadA lock playerA, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);
|
||||
|
||||
// printf("shareA = shareA(%d) + 2\n", shareA);
|
||||
argA->shareA += 2;
|
||||
|
||||
|
||||
sleep(1);
|
||||
PLAYER_MUXTEX_LOCK(argA->player_B);
|
||||
printf("threadA lock playerB, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);
|
||||
|
||||
// printf("shareA = shareB(%d) + 2\n", shareB);
|
||||
argA->shareA = argA->shareB + 2;
|
||||
|
||||
|
||||
PLAYER_MUXTEX_UNLOCK(argA->player_B);
|
||||
printf("threadA unlock playerB, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);
|
||||
|
||||
PLAYER_MUXTEX_UNLOCK(argA->player_A);
|
||||
printf("threadA unlock playerA, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);
|
||||
}
|
||||
|
||||
void * thread_fun_B(void * arg)
|
||||
{
|
||||
T_ARG *argB = (T_ARG *)arg;
|
||||
|
||||
PLAYER_MUXTEX_LOCK(argB->player_B);
|
||||
printf("threadB lock playerB, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);
|
||||
|
||||
// printf("shareB = shareB(%d) + 3\n", shareB);
|
||||
argB->shareB += 3;
|
||||
|
||||
|
||||
sleep(1);
|
||||
PLAYER_MUXTEX_LOCK(argB->player_A);
|
||||
printf("threadB lock playerA, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);
|
||||
|
||||
// printf("shareB = shareA(%d) + 3\n", shareA);
|
||||
argB->shareB = argB->shareA + 3;
|
||||
|
||||
|
||||
PLAYER_MUXTEX_UNLOCK(argB->player_A);
|
||||
printf("threadB unlock playerA, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);
|
||||
|
||||
PLAYER_MUXTEX_UNLOCK(argB->player_B);
|
||||
printf("threadB unlock playerB, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);
|
||||
}
|
||||
|
||||
void init(T_ARG *arg)
|
||||
{
|
||||
arg->shareA = 0;
|
||||
arg->shareB = 0;
|
||||
arg->count = 0;
|
||||
|
||||
list = (T_LIST *)malloc(sizeof(T_LIST));
|
||||
list->list_count = 0;
|
||||
|
||||
arg->player_A = (T_PLAYER *)malloc(sizeof(T_PLAYER));
|
||||
arg->player_B = (T_PLAYER *)malloc(sizeof(T_PLAYER));
|
||||
|
||||
arg->player_A->player_mux = (T_MUTE *)malloc(sizeof(T_MUTE));
|
||||
arg->player_B->player_mux = (T_MUTE *)malloc(sizeof(T_MUTE));
|
||||
|
||||
PLAYER_MUXTEX_INIT(arg->player_A);
|
||||
PLAYER_MUXTEX_INIT(arg->player_B);
|
||||
}
|
||||
|
||||
void free_player(T_ARG *arg)
|
||||
{
|
||||
free(arg->player_A);
|
||||
free(arg->player_B);
|
||||
|
||||
free(arg);
|
||||
|
||||
free(list);
|
||||
}
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
T_ARG *arg = (T_ARG *)malloc(sizeof(T_ARG));
|
||||
|
||||
init(arg);
|
||||
|
||||
int ret = -1;
|
||||
|
||||
pthread_t threadA, threadB, thread_detect_deadlock, thread_detect_count;
|
||||
ret = pthread_create(&threadA, NULL, thread_fun_A, (void *)arg);
|
||||
if(ret != 0)
|
||||
{
|
||||
printf("Pthread create error!\n");
|
||||
}
|
||||
|
||||
ret = pthread_create(&threadB, NULL, thread_fun_B, (void *)arg);
|
||||
if(ret != 0)
|
||||
{
|
||||
printf("Pthread create error!\n");
|
||||
}
|
||||
|
||||
ret = pthread_create(&thread_detect_deadlock, NULL, loop_detect_deadlock_thread, (void *)arg);
|
||||
if(ret != 0)
|
||||
{
|
||||
printf("Pthread create error!\n");
|
||||
}
|
||||
|
||||
ret = pthread_create(&thread_detect_count, NULL, loop_detect_count_thread, (void *)arg);
|
||||
if(ret != 0)
|
||||
{
|
||||
printf("Pthread create error!\n");
|
||||
}
|
||||
|
||||
pthread_join(threadA, NULL);
|
||||
pthread_join(threadB, NULL);
|
||||
|
||||
pthread_cancel(thread_detect_count);
|
||||
pthread_cancel(thread_detect_deadlock);
|
||||
pthread_join(thread_detect_count, NULL);
|
||||
pthread_join(thread_detect_deadlock, NULL);
|
||||
|
||||
PLAYER_MUXTEX_DESTROY;
|
||||
|
||||
printf("shareA: %d, shareB: %d\n", arg->shareA, arg->shareB);
|
||||
free_player(arg);
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,126 @@
|
||||
// 2010年 07月 28日 星期三 13:01:43 CST
|
||||
// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)
|
||||
// K.I.S.S
|
||||
// S.P.O.T
|
||||
// linux-2.6.XX/Document/
|
||||
// linux-2.6.xx/kernel/futex.c
|
||||
// http://blog.csdn.net/cybertan/article/details/8096863
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <linux/futex.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define gettid( ) syscall(SYS_gettid)
|
||||
|
||||
#define futex(addr1, op, val, rel, addr2, val3) \
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
|
||||
typedef struct futex_t {
|
||||
int wake;
|
||||
int lock;
|
||||
int wlock;
|
||||
}futex_t;
|
||||
|
||||
inline static void futex_init(futex_t *);
|
||||
inline static int futex_wake(futex_t *);
|
||||
inline static int futex_wait(futex_t *);
|
||||
inline static int futex_lock(futex_t *);
|
||||
inline static int futex_unlock(futex_t *);
|
||||
|
||||
|
||||
void *print_msg(void *arg);
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
struct futex_t ftx;
|
||||
pthread_t tid[2];
|
||||
futex_init(&ftx);
|
||||
futex_wake(&ftx);
|
||||
|
||||
|
||||
pthread_create(&tid[0], 0, print_msg, (void *)&ftx);
|
||||
pthread_create(&tid[1], 0, print_msg, (void *)&ftx);
|
||||
|
||||
pthread_join(tid[0], 0);
|
||||
pthread_join(tid[1], 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *print_msg(void *arg){
|
||||
|
||||
struct futex_t *ftx = (struct futex_t *)arg;
|
||||
unsigned long count = 0;
|
||||
struct args *curr_arg = (struct args*)arg;
|
||||
cpu_set_t mask;
|
||||
|
||||
printf("tid = %d(%ld) START\n", gettid( ), pthread_self( ));
|
||||
|
||||
|
||||
CPU_ZERO(&mask);
|
||||
//CPU_SET(curr_arg->cpu, &mask);
|
||||
CPU_SET(0, &mask);
|
||||
|
||||
if (pthread_setaffinity_np(pthread_self( ), sizeof(mask), &mask) < 0) {
|
||||
perror("sched_setaffinity");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("tid = %d affine to CPU %d\n", gettid( ), 0);
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
futex_wait(&ftx);
|
||||
|
||||
printf("tid = %d, count = %ld\n", gettid( ), count);
|
||||
count++;
|
||||
usleep(0);
|
||||
|
||||
futex_wake(&ftx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline static void futex_init(futex_t *ftx)
|
||||
{
|
||||
ftx->lock = 0;
|
||||
ftx->wake = 0;
|
||||
ftx->wlock = 0;
|
||||
}
|
||||
|
||||
inline static int futex_wake(futex_t *ftx)
|
||||
{
|
||||
__sync_fetch_and_add(&ftx->wake, 1);
|
||||
//__sync_lock_test_and_set(&ftx->wake, 1);
|
||||
return futex(&ftx->wake, FUTEX_WAKE, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_wait(futex_t *ftx)
|
||||
{
|
||||
futex(&ftx->wlock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
int ret = futex(&ftx->wake, FUTEX_WAIT, 0, 0, 0, 0);
|
||||
__sync_fetch_and_sub(&ftx->wake, 1);
|
||||
futex(&ftx->wlock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
return (ret && errno == EWOULDBLOCK ? 1 : ret);
|
||||
}
|
||||
|
||||
inline static int futex_lock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_unlock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// 2010年 07月 28日 星期三 13:01:43 CST
|
||||
// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)
|
||||
// K.I.S.S
|
||||
// S.P.O.T
|
||||
// linux-2.6.XX/Document/
|
||||
// linux-2.6.xx/kernel/futex.c
|
||||
// http://blog.csdn.net/cybertan/article/details/8096863
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <linux/futex.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define gettid( ) syscall(SYS_gettid)
|
||||
|
||||
#define futex(addr1, op, val, rel, addr2, val3) \
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
|
||||
typedef struct futex_t {
|
||||
int wake;
|
||||
int lock;
|
||||
int wlock;
|
||||
}futex_t;
|
||||
|
||||
inline static void futex_init(futex_t *);
|
||||
inline static int futex_wake(futex_t *);
|
||||
inline static int futex_wait(futex_t *);
|
||||
inline static int futex_lock(futex_t *);
|
||||
inline static int futex_unlock(futex_t *);
|
||||
|
||||
|
||||
static void *work_thread(void *);
|
||||
static void *work_send(void *);
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
struct futex_t ftx;
|
||||
pthread_t tid[2];
|
||||
futex_init(&ftx);
|
||||
futex_wake(&ftx);
|
||||
|
||||
|
||||
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
pthread_create(&tid[i], 0, work_thread, (void *)&ftx);
|
||||
pthread_join(tid[i], 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *work_thread(void *p)
|
||||
{
|
||||
struct futex_t *ftx = (struct futex_t *)p;
|
||||
//sleep(2);
|
||||
|
||||
int count = 0;
|
||||
|
||||
printf("%d\n", gettid( ));
|
||||
for(;;) {
|
||||
futex_wait(ftx);
|
||||
futex_lock(ftx);
|
||||
|
||||
printf("tid = %d, count = %ld\n", gettid( ), count);
|
||||
count++;
|
||||
usleep(1000000);
|
||||
|
||||
futex_unlock(ftx);
|
||||
futex_wake(ftx);
|
||||
}
|
||||
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
|
||||
inline static void futex_init(futex_t *ftx)
|
||||
{
|
||||
ftx->lock = 0;
|
||||
ftx->wake = 0;
|
||||
ftx->wlock = 0;
|
||||
}
|
||||
|
||||
inline static int futex_wake(futex_t *ftx)
|
||||
{
|
||||
__sync_fetch_and_add(&ftx->wake, 1);
|
||||
//__sync_lock_test_and_set(&ftx->wake, 1);
|
||||
return futex(&ftx->wake, FUTEX_WAKE, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_wait(futex_t *ftx)
|
||||
{
|
||||
futex(&ftx->wlock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
int ret = futex(&ftx->wake, FUTEX_WAIT, 0, 0, 0, 0);
|
||||
__sync_fetch_and_sub(&ftx->wake, 1);
|
||||
futex(&ftx->wlock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
return (ret && errno == EWOULDBLOCK ? 1 : ret);
|
||||
}
|
||||
|
||||
inline static int futex_lock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_unlock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
// 2010年 07月 28日 星期三 13:01:43 CST
|
||||
// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)
|
||||
// K.I.S.S
|
||||
// S.P.O.T
|
||||
// linux-2.6.XX/Document/
|
||||
// linux-2.6.xx/kernel/futex.c
|
||||
// http://blog.csdn.net/cybertan/article/details/8096863
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <linux/futex.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define gettid( ) syscall(SYS_gettid)
|
||||
|
||||
#define futex(addr1, op, val, rel, addr2, val3) \
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
|
||||
typedef struct futex_t {
|
||||
int wake;
|
||||
int lock;
|
||||
int wlock;
|
||||
}futex_t;
|
||||
|
||||
inline static void futex_init(futex_t *);
|
||||
inline static int futex_wake(futex_t *);
|
||||
inline static int futex_wait(futex_t *);
|
||||
inline static int futex_lock(futex_t *);
|
||||
inline static int futex_unlock(futex_t *);
|
||||
|
||||
|
||||
static void *work_thread(void *);
|
||||
static void *work_send(void *);
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
struct futex_t ftx;
|
||||
pthread_t tid[2];
|
||||
futex_init(&ftx);
|
||||
futex_wake(&ftx);
|
||||
|
||||
|
||||
pthread_create(&tid[0], 0, work_thread, (void *)&ftx);
|
||||
pthread_create(&tid[1], 0, work_thread, (void *)&ftx);
|
||||
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
//pthread_create(&tid[i], 0, work_thread, (void *)&ftx);
|
||||
pthread_join(tid[i], 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *work_thread(void *p)
|
||||
{
|
||||
struct futex_t *ftx = (struct futex_t *)p;
|
||||
//sleep(2);
|
||||
|
||||
int count = 0;
|
||||
|
||||
for(;;) {
|
||||
futex_wait(ftx);
|
||||
futex_lock(ftx);
|
||||
|
||||
printf("tid = %d, count = %ld\n", gettid( ), count);
|
||||
count++;
|
||||
usleep(1000000);
|
||||
|
||||
futex_unlock(ftx);
|
||||
futex_wake(ftx);
|
||||
}
|
||||
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
|
||||
inline static void futex_init(futex_t *ftx)
|
||||
{
|
||||
ftx->lock = 0;
|
||||
ftx->wake = 0;
|
||||
ftx->wlock = 0;
|
||||
}
|
||||
|
||||
inline static int futex_wake(futex_t *ftx)
|
||||
{
|
||||
__sync_fetch_and_add(&ftx->wake, 1);
|
||||
//__sync_lock_test_and_set(&ftx->wake, 1);
|
||||
return futex(&ftx->wake, FUTEX_WAKE, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_wait(futex_t *ftx)
|
||||
{
|
||||
futex(&ftx->wlock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
int ret = futex(&ftx->wake, FUTEX_WAIT, 0, 0, 0, 0);
|
||||
__sync_fetch_and_sub(&ftx->wake, 1);
|
||||
futex(&ftx->wlock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
return (ret && errno == EWOULDBLOCK ? 1 : ret);
|
||||
}
|
||||
|
||||
inline static int futex_lock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_unlock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,120 @@
|
||||
// 2010年 07月 28日 星期三 13:01:43 CST
|
||||
// author: 李小丹(Li Shao Dan) 字 殊恒(shuheng)
|
||||
// K.I.S.S
|
||||
// S.P.O.T
|
||||
// linux-2.6.XX/Document/
|
||||
// linux-2.6.xx/kernel/futex.c
|
||||
// http://blog.csdn.net/cybertan/article/details/8096863
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <linux/futex.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define gettid( ) syscall(SYS_gettid)
|
||||
|
||||
#define futex(addr1, op, val, rel, addr2, val3) \
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
|
||||
typedef struct futex_t {
|
||||
int wake;
|
||||
int lock;
|
||||
int wlock;
|
||||
}futex_t;
|
||||
|
||||
inline static void futex_init(futex_t *);
|
||||
inline static int futex_wake(futex_t *);
|
||||
inline static int futex_wait(futex_t *);
|
||||
inline static int futex_lock(futex_t *);
|
||||
inline static int futex_unlock(futex_t *);
|
||||
|
||||
|
||||
static void *work_thread(void *);
|
||||
static void *work_send(void *);
|
||||
|
||||
static int count = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
struct futex_t ftx;
|
||||
pthread_t tid[6];
|
||||
|
||||
futex_init(&ftx);
|
||||
|
||||
pthread_create(&tid[3], 0, work_send, (void *)&ftx);
|
||||
pthread_create(&tid[1], 0, work_thread, (void *)&ftx);
|
||||
pthread_create(&tid[2], 0, work_thread, (void *)&ftx);
|
||||
pthread_create(&tid[5], 0, work_send, (void *)&ftx);
|
||||
pthread_create(&tid[0], 0, work_thread, (void *)&ftx);
|
||||
pthread_create(&tid[4], 0, work_send, (void *)&ftx);
|
||||
|
||||
for(int i = 0; i < 6; ++i)
|
||||
pthread_join(tid[i], 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *work_thread(void *p)
|
||||
{
|
||||
struct futex_t *ftx = (struct futex_t *)p;
|
||||
//sleep(2);
|
||||
|
||||
for(;;) {
|
||||
futex_wait(ftx);
|
||||
|
||||
futex_lock(ftx);
|
||||
|
||||
printf("tid = %d, count = %ld\n", gettid( ), count);
|
||||
count++;
|
||||
usleep(1000000);
|
||||
|
||||
futex_unlock(ftx);
|
||||
}
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
void *work_send(void *p)
|
||||
{
|
||||
futex_t *ftx = (struct futex_t *)p;
|
||||
for(int i = 0; i < 3000; ++i)
|
||||
futex_wake(ftx);
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
inline static void futex_init(futex_t *ftx)
|
||||
{
|
||||
ftx->lock = 0;
|
||||
ftx->wake = 0;
|
||||
ftx->wlock = 0;
|
||||
}
|
||||
|
||||
inline static int futex_wake(futex_t *ftx)
|
||||
{
|
||||
__sync_fetch_and_add(&ftx->wake, 1);
|
||||
//__sync_lock_test_and_set(&ftx->wake, 1);
|
||||
return futex(&ftx->wake, FUTEX_WAKE, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_wait(futex_t *ftx)
|
||||
{
|
||||
futex(&ftx->wlock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
int ret = futex(&ftx->wake, FUTEX_WAIT, 0, 0, 0, 0);
|
||||
__sync_fetch_and_sub(&ftx->wake, 1);
|
||||
futex(&ftx->wlock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
return (ret && errno == EWOULDBLOCK ? 1 : ret);
|
||||
}
|
||||
|
||||
inline static int futex_lock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_LOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline static int futex_unlock(futex_t *ftx)
|
||||
{
|
||||
return futex(&ftx->lock, FUTEX_UNLOCK_PI, 0, 0, 0, 0);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*************************************************************************
|
||||
> File Name: mutex_bug.c
|
||||
> Author: GatieMe
|
||||
> Mail: gatieme@163.com
|
||||
> Created Time: Sat 09 Sep 2017 11:39:26 AM CST
|
||||
************************************************************************/
|
||||
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <sched.h>
|
||||
|
||||
#include <pthread.h> /* For pthread */
|
||||
|
||||
#include <unistd.h> /* */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(MUTEX)
|
||||
pthread_mutex_t lock;
|
||||
#define LOCK_INIT( ) pthread_mutex_init(&lock, NULL)
|
||||
#define LOCK( ) pthread_mutex_lock(&lock)
|
||||
#define UNLOCK( ) pthread_mutex_unlock(&lock)
|
||||
#define LOCK_DESTROY( ) pthread_mutex_destroy(&lock)
|
||||
#elif defined(SEM)
|
||||
#include <semaphore.h>
|
||||
sem_t lock;
|
||||
#define LOCK_INIT( ) sem_init(&lock, 0, 1)
|
||||
#define LOCK( ) sem_wait(&lock)
|
||||
#define UNLOCK( ) sem_post(&lock)
|
||||
#define LOCK_DESTROY( ) sem_destroy(&lock)
|
||||
#else
|
||||
#define LOCK_INIT( )
|
||||
#define LOCK( )
|
||||
#define UNLOCK( )
|
||||
#define LOCK_DESTROY( )
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
#include <linux/unistd.h>
|
||||
pid_t gettid(void)
|
||||
{
|
||||
return syscall(__NR_gettid);
|
||||
}
|
||||
#endif
|
||||
#include <sys/syscall.h>
|
||||
|
||||
pid_t gettid(void)
|
||||
{
|
||||
return syscall(SYS_gettid);
|
||||
}
|
||||
struct args
|
||||
{
|
||||
unsigned long sleeptime;
|
||||
int cpu;
|
||||
};
|
||||
|
||||
void *print_msg(void *arg){
|
||||
|
||||
unsigned long count = 0;
|
||||
struct args *curr_arg = (struct args*)arg;
|
||||
cpu_set_t mask;
|
||||
|
||||
printf("tid = %d(%ld) START\n", gettid( ), pthread_self( ));
|
||||
|
||||
|
||||
CPU_ZERO(&mask);
|
||||
//CPU_SET(curr_arg->cpu, &mask);
|
||||
CPU_SET(0, &mask);
|
||||
|
||||
if (pthread_setaffinity_np(pthread_self( ), sizeof(mask), &mask) < 0) {
|
||||
perror("sched_setaffinity");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("tid = %d affine to CPU %d\n", gettid( ), curr_arg->cpu);
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
LOCK( );
|
||||
|
||||
printf("tid = %d, count = %ld\n", gettid( ), count);
|
||||
count++;
|
||||
usleep(curr_arg->sleeptime);
|
||||
|
||||
UNLOCK( );
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char** argv){
|
||||
pthread_t id1;
|
||||
pthread_t id2;
|
||||
|
||||
struct args arg1 = { .sleeptime = 10000000, .cpu = 0 };
|
||||
struct args arg2 = { .sleeptime = 10000000, .cpu = 0 };
|
||||
|
||||
LOCK_INIT( );
|
||||
|
||||
|
||||
printf("MAIN pid = %d\n", getpid( ));
|
||||
getchar( );
|
||||
|
||||
pthread_create(&id1, NULL, print_msg, &arg1);
|
||||
pthread_create(&id2, NULL, print_msg, &arg2);
|
||||
|
||||
pthread_join(id1, NULL);
|
||||
pthread_join(id2, NULL);
|
||||
|
||||
LOCK_DESTROY( );
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
probe begin
|
||||
{
|
||||
printf("futex begin\n");
|
||||
}
|
||||
|
||||
probe kernel.function("do_futex")
|
||||
{
|
||||
if(pid( ) == target( ))
|
||||
{
|
||||
printf("[do_futex] : tid = %d\n", tid( ));
|
||||
}
|
||||
}
|
||||
|
||||
probe kernel.function("futex_wait")
|
||||
{
|
||||
if(pid( ) == target( ))
|
||||
{
|
||||
printf("[futex_wait] : tid = %d\n", tid( ));
|
||||
}
|
||||
}
|
||||
|
||||
probe kernel.function("futex_wake")
|
||||
{
|
||||
if(pid( ) == target( ))
|
||||
{
|
||||
printf("[futex_wake] : tid = %d\n", tid( ));
|
||||
}
|
||||
}
|
||||
|
||||
probe kernel.function("__schedule")
|
||||
{
|
||||
if(pid( ) == target( ))
|
||||
{
|
||||
printf("[__schedule] : tid = %d\n", tid( ));
|
||||
|
||||
}
|
||||
}
|
||||
probe end
|
||||
{
|
||||
printf("futex end\n");
|
||||
}
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,97 @@
|
||||
/*************************************************************************
|
||||
> File Name: mutex_bug.c
|
||||
> Author: GatieMe
|
||||
> Mail: gatieme@163.com
|
||||
> Created Time: Sat 09 Sep 2017 11:39:26 AM CST
|
||||
************************************************************************/
|
||||
|
||||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <sched.h>
|
||||
|
||||
#include <pthread.h> /* For pthread */
|
||||
|
||||
#include <unistd.h> /* */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
pid_t gettid(void)
|
||||
{
|
||||
return syscall(SYS_gettid);
|
||||
}
|
||||
struct args
|
||||
{
|
||||
unsigned long sleeptime;
|
||||
int cpu;
|
||||
};
|
||||
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define futex(addr1, op, val, rel, addr2, val3) \
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
|
||||
long lock;
|
||||
void *print_msg(void *arg){
|
||||
|
||||
unsigned long count = 0;
|
||||
struct args *curr_arg = (struct args*)arg;
|
||||
cpu_set_t mask;
|
||||
|
||||
printf("tid = %d(%ld) START\n", gettid( ), pthread_self( ));
|
||||
|
||||
|
||||
CPU_ZERO(&mask);
|
||||
//CPU_SET(curr_arg->cpu, &mask);
|
||||
CPU_SET(0, &mask);
|
||||
|
||||
if (pthread_setaffinity_np(pthread_self( ), sizeof(mask), &mask) < 0) {
|
||||
perror("sched_setaffinity");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("tid = %d affine to CPU %d\n", gettid( ), curr_arg->cpu);
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
futex(&lock, FUTEX_WAIT, 1, NULL, NULL, 0);
|
||||
|
||||
printf("tid = %d, count = %ld\n", gettid( ), count);
|
||||
count++;
|
||||
usleep(curr_arg->sleeptime);
|
||||
|
||||
futex(&lock, FUTEX_WAKE, 0, NULL, NULL, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char** argv){
|
||||
pthread_t id1;
|
||||
pthread_t id2;
|
||||
|
||||
struct args arg1 = { .sleeptime = 1000000, .cpu = 0 };
|
||||
struct args arg2 = { .sleeptime = 1000000, .cpu = 0 };
|
||||
|
||||
|
||||
lock = 1;
|
||||
|
||||
printf("MAIN pid = %d\n", getpid( ));
|
||||
|
||||
|
||||
pthread_create(&id1, NULL, print_msg, &arg1);
|
||||
pthread_create(&id2, NULL, print_msg, &arg2);
|
||||
|
||||
pthread_join(id1, NULL);
|
||||
pthread_join(id2, NULL);
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,37 @@
|
||||
// http://blog.csdn.net/jianchaolv/article/details/7544316
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
sem_t sem_a;
|
||||
void *task1();
|
||||
|
||||
int main(void){
|
||||
int ret = 0;
|
||||
pthread_t thrd1;
|
||||
pthread_t thrd2;
|
||||
|
||||
printf("pid = %d\n", getpid( ));
|
||||
sem_init(&sem_a,0,1);
|
||||
ret=pthread_create(&thrd1,NULL,task1,NULL); //创建子线程
|
||||
ret=pthread_create(&thrd2,NULL,task1,NULL); //创建子线程
|
||||
|
||||
pthread_join(thrd1,NULL); //等待子线程结束
|
||||
pthread_join(thrd2,NULL); //等待子线程结束
|
||||
|
||||
}
|
||||
|
||||
void *task1()
|
||||
{
|
||||
int sval = 0;
|
||||
while(1)
|
||||
{
|
||||
sem_wait(&sem_a); //持有信号量
|
||||
sleep(1); //do_nothing
|
||||
sem_getvalue(&sem_a,&sval);
|
||||
printf("tid = %ld, sem value = %d\n", pthread_self( ), sval);
|
||||
sem_post(&sem_a); //释放信号量
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#
|
||||
#http://blog.sina.com.cn/s/blog_694f2ae70101amh6.html
|
||||
#
|
||||
target=futex_align
|
||||
|
||||
CURRENT_BIN_DIR=futex_bug
|
||||
INSTALL_ROOT_DIR=~/Work/Kernel/runninglinuxkernel/filesystem
|
||||
INSTALL_HOME_DIR=home/chengjian
|
||||
|
||||
ifeq ($(ARCH), arm64)
|
||||
CROSS_COMPILE=/opt/arm/toolschain/linaro/gcc-linaro-7.1.1-2017.08-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
ARCH_FILE_DIR=_install_arm64
|
||||
else ifeq ($(ARCH), arm)
|
||||
CROSS_COMPILE=arm-linux-gnueabi-
|
||||
ARCH_FILE_DIR=_install_arm32
|
||||
else # ifeq ($(ARCH), x86_64)
|
||||
ARCH_FILE_DIR=_install_x86
|
||||
endif
|
||||
|
||||
INSTALL_BIN_DIR=$(INSTALL_ROOT_DIR)/$(ARCH_FILE_DIR)/$(INSTALL_HOME_DIR)/ #$(CURRENT_BIN_DIR)
|
||||
|
||||
CC=${CROSS_COMPILE}gcc
|
||||
AS=${CROSS_COMPILE}as
|
||||
LD=${CROSS_COMPILE}ld
|
||||
LDFLAGS+=-static
|
||||
|
||||
|
||||
all : $(target)
|
||||
|
||||
futex_align:futex_align.o
|
||||
$(CC) $^ -o $@ $(LDFLAGS)
|
||||
@echo "ptrace singlestep..."
|
||||
|
||||
|
||||
%.o : %.c
|
||||
$(CC) -c $^ -o $@ $(CFLAGS) $(DEFINES)
|
||||
|
||||
%.o : %.cpp
|
||||
$(CXX) -c $^ -o $@ $(CFLAGS) $(DEFINES)
|
||||
|
||||
clean :
|
||||
rm -rf *.o
|
||||
rm -rf $(target)
|
||||
|
||||
install :
|
||||
mkdir -p $(CURRENT_BIN_DIR)
|
||||
cp $(target) $(CURRENT_BIN_DIR)
|
||||
#echo $(INSTALL_BIN_DIR)
|
||||
cp -rf $(CURRENT_BIN_DIR) $(INSTALL_BIN_DIR)
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
// futex_align.c
|
||||
#include <stdio.h>
|
||||
#include <linux/futex.h>
|
||||
#include <syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char *p = malloc(128);
|
||||
|
||||
struct robust_list_head *ro1;
|
||||
struct robust_list *entry;
|
||||
struct robust_list *pending;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
pid_t pid = getpid();
|
||||
|
||||
printf("size = %d, p %p pid [%d] \n",
|
||||
sizeof(struct robust_list_head), p, pid);
|
||||
|
||||
ro1 = p;
|
||||
entry = p + 20;
|
||||
pending = p + 40;
|
||||
|
||||
ro1->list.next = entry;
|
||||
ro1->list_op_pending = pending;
|
||||
|
||||
entry->next = &(ro1->list);
|
||||
|
||||
ro1->futex_offset = 41;
|
||||
|
||||
*((int *)((char *)entry + 41)) = pid;
|
||||
|
||||
printf(" entry + offert [%p] [%d] \n",
|
||||
(int *)((char *)entry + 41),
|
||||
*((int *)((char *)entry + 41)));
|
||||
|
||||
ret = syscall(SYS_set_robust_list, ro1,
|
||||
sizeof(struct robust_list_head));
|
||||
|
||||
printf("ret = [%d]\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user