进程互斥锁的初步实现(上)

问题

Mutex 相关函数接口处于用户态还是内核态?

问题中的问题

Mutex操作可能导致任务状态的切换 (执行态 => 阻塞态),其功能只能由内核实现

通过 0x80 中断从用户态调用内核功能

系统调用重设计

 互斥锁系统调用功能设计

 

整体调用流程

 D.T.OS 架构图

互斥锁模块的创建

mutex.h


#ifndef MUTEX_H
#define MUTEX_H

#include "type.h"

typedef void  Mutex;

void MutexModInit();
void MutexCallHandler(uint cmd, uint param);

Mutex* SysCreateMutex();
void SysEnterCritical(Mutex* mutex);
void SysExitCritical(Mutex* mutex);
void SysDestroyMutex(Mutex* mutex);


#endif

mutex.c


#include "mutex.h"

void MutexModInit()
{

}

void MutexCallHandler(uint cmd, uint param)
{
	if(cmd == 0)
	{
		PrintString("Muetx Create\n");
		PrintIntHex(param);
		PrintChar('\n');
	}
	else if(cmd == 1)	
	{
		PrintString("Muetx Enter\n");
	}
	else if(cmd == 2)
	{
		PrintString("Muetx Exit\n");
	}
	else
	{
		PrintString("Muetx Destroy\n");
	}
}

syscall.h


#ifndef SYSCALL_H
#define SYSCALL_H

#include "type.h"

void Exit();
uint CreateMutex();
void EnterCritical(uint mutex);
void ExitCritical(uint mutex);
void DestroyMutex(uint mutex);

#endif

syscall.c


#include "syscall.h"


void Exit()
{
	asm volatile(
	    "movl $0, %eax \n"    // type
	    "int $0x80 \n"
	);
}

uint CreateMutex()
{
	volatile uint ret = 0;	
	
	PrintString("&ret = ");
	PrintIntHex(&ret);
	
	asm volatile(
	    "movl $1, %%eax \n"    // type
	    "movl $0, %%ebx \n"    // cmd
	    "movl %0, %%ecx \n"    // param1
	    "int $0x80      \n"
	    :
	    : "r"(&ret)
	    : "eax", "ebx", "ecx", "edx"
	);
	
	return ret;
}

void EnterCritical(uint mutex)
{
	asm volatile(
	    "movl $1, %%eax \n"    // type
	    "movl $1, %%ebx \n"    // cmd
	    "movl %0, %%ecx \n"    // param1
	    "int $0x80      \n"
	    :
	    : "r"(mutex)
	    : "eax", "ebx", "ecx", "edx"
	);
}

void ExitCritical(uint mutex)
{
	asm volatile(
	    "movl $1, %%eax \n"    // type
	    "movl $2, %%ebx \n"    // cmd
	    "movl %0, %%ecx \n"    // param1
	    "int $0x80      \n"
	    :
	    : "r"(mutex)
	    : "eax", "ebx", "ecx", "edx"
	);
}

void DestroyMutex(uint mutex)
{
	asm volatile(
	    "movl $1, %%eax \n"    // type
	    "movl $3, %%ebx \n"    // cmd
	    "movl %0, %%ecx \n"    // param1
	    "int $0x80      \n"
	    :
	    : "r"(mutex)
	    : "eax", "ebx", "ecx", "edx"
	);
}

ihandler.c

void SysCallHandler(uint type, uint cmd, uint param1, uint param2)    // __cdcel__
{
	switch(type)
	{
		case 0:
			KillTask();
			break;
		case 1:
			MutexCallHandler(cmd, param1);
			break;
		default:
			break;
	}
}

kentry.asm

;
;
SysCallHandlerEntry:
BeginISR
	push edx
	push ecx
	push ebx
	push eax
	
    call SysCallHandler
    
    pop eax
    pop ebx
    pop ecx
    pop edx
     
EndISR

task.c

void TaskEntry()
{
	if(gCTaskAddr != NULL)
	{
		gCTaskAddr->tmain();
	}
	
	// to destory current task here
	asm volatile(
	    "movl $0, %eax \n"
	    "int $0x80 \n"
	);
	
	while(1);    // TODO: schedule next task to run
}

app.c

void TaskA()
{
    int i = 0;
    volatile uint mutex = 0;
    
    SetPrintPos(0, 12);
    
    PrintString(__FUNCTION__);
    
    PrintChar('\n');
    
    mutex = CreateMutex();
    
    EnterCritical(mutex);
    
    ExitCritical(mutex);
    
    DestroyMutex(mutex);
}

mutex.h 中声明了 4 个 Mutex 的相关函数,这是内核中的函数,应用程序需要通过 0x80 号中断来调用内核函数,在 syscall.h 中实现了给应用程序提供的系统函数接口,利用 type 和 cmd 通过 0x80 号中断来转移特权级,执行相应的内核函数。

修改后的 SysCallHandler 中有4个参数,因为不同特权级对应不同的栈,所以在特权级转移的时候,如若我们想要保存参数,那么相应的参数就不能入栈,而是得保存在寄存器中。

type 为1就会调用 MutexCallHandler 函数, MutexCallHandler 函数根据 cmd 再调用相应的 Mutex函数。

我们通过系统函数接口,可以成功升高特权级去执行内核的函数,并且内核也能成功的接收到应用程序传递过来的参数。 

思考

在内核中实现互斥锁的功能是必要的吗?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值