⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 program11.c

📁 嵌入式系统基础课件
💻 C
字号:
#include "libepc.h"
#include "os_cpu.h"
#include "os_cfg.h"
#include "ucos_ii.h"
#include <stdlib.h>

#define	STACK_SIZE	1000

#define	THREADS		2	/* No more than 6 */
#define	RESOURCES	2	/* No more than 8 */

typedef enum
	{
	DORMANT	= 0,
	PENDING = 1,
	READY	= 2,
	RUNNING	= 3,
	SLEEPING= 4
	} THREAD_STATE ;

extern void		AcquireResources(int, int) ;
extern void		ReleaseResources(int, int) ;

BOOL			Acquire1Resource(int, int) ;
void			Release1Resource(int, int) ;

PRIVATE void		Analyze(void) ;
PRIVATE OS_STK *	CreateStack(void) ;
PRIVATE BOOL		Deadlock(int) ;
PRIVATE void		Monitor() ;
PRIVATE void		Thread() ;

PRIVATE OS_EVENT *	semaphore[RESOURCES] ;
PRIVATE THREAD_STATE	thread_state[THREADS] ;
PRIVATE BOOL		pending[THREADS][RESOURCES] ;
PRIVATE BOOL		acquired[THREADS][RESOURCES] ;
PRIVATE BOOL		waiting[THREADS][THREADS] ;
PRIVATE unsigned	executions[THREADS] ;

int main()
	{
	int resource, priority ;

	srandom((int) CPU_Clock_Cycles()) ;

	ClearScreen(0x07) ;
	SetCursorVisible(FALSE) ;

	OSInit() ;

	for (resource = 0; resource < RESOURCES; resource++)
		{
		semaphore[resource] = OSSemCreate(1) ;
		}

	for (priority = 0; priority < THREADS; priority++)
		{
		OSTaskCreate(Thread, NULL, CreateStack(), priority) ;
		}
	OSTaskCreate(Monitor, NULL, CreateStack(), priority) ;

	OSStart() ;

	return 0 ;
	}

BOOL Acquire1Resource(int thread, int resource)
	{
	if (!acquired[thread][resource])
		{
		BYTE8 err ;

		OSSemPend(semaphore[resource], 1, &err) ;
		OSTimeDly(random() % 50) ;
		if (err != OS_NO_ERR)
			{
			pending[thread][resource] = TRUE ;
			thread_state[thread] = PENDING ;
			return FALSE ;
			}

		acquired[thread][resource] = TRUE ;
		pending[thread][resource] = FALSE ;
		return TRUE ;
		}

	return FALSE ;
	}

void Release1Resource(int thread, int resource)
	{
	OSSemPost(semaphore[resource]) ;
	acquired[thread][resource] = FALSE ;
	}

PRIVATE void Thread(void)
	{
	static int threads = 0 ;
	int thread = threads++ ;

	executions[thread] = 0 ;
	for (;;)
		{
		DWORD32 timer ;

		thread_state[thread] = SLEEPING ;
		OSTimeDly(random() % 1000) ;

		AcquireResources(thread, RESOURCES) ;
		thread_state[thread] = RUNNING ;

		/* Simulate doing some work for up to 1 sec */
		timer = OSTimeGet() + (random() % 1000) ;
		while (OSTimeGet() < timer) OSTimeDly(1) ;

		ReleaseResources(thread, RESOURCES) ;
		++executions[thread] ;
		}
	}

PRIVATE void Analyze(void)
	{
	int t1, t2, r ;

	memset(waiting, FALSE, sizeof(waiting)) ;
	for (r = 0; r < RESOURCES; r++)
		{
		for (t2 = 0; t2 < THREADS; t2++)
			{
			if (!acquired[t2][r]) continue ;
			for (t1 = 0; t1 < THREADS; t1++)
				{
				if (!pending[t1][r]) continue ;
				waiting[t1][t2] = TRUE ;
				}
			break ;
			}
		}

	}

PRIVATE BOOL Deadlock(int thread)
	{
	int t1, t2, cycles ;

	if (thread_state[thread] != PENDING) return FALSE ;

	t1 = thread ;
	for (cycles = 0; cycles < THREADS; cycles++)
		{
		for (t2 = 0; t2 < THREADS; t2++)
			{
			if (waiting[t1][t2]) break ;
			}
		if (t2 == THREADS) return FALSE ;
		if (t2 == thread) break ;
		t1 = t2 ;
		}

	return TRUE ;
	}

PRIVATE void Monitor(void)
	{
#	define THREAD_SPACING 10
	int thread, resource, row, col, row1, col1 ;

	SetCursorPosition(24, 35) ;
	PutString("Updates: ") ;

	row1 = (25 - (6 + 2 * RESOURCES)) / 2 ;
	col1 = (80 - (13 + THREAD_SPACING * THREADS)) / 2 ;

	row = row1 ;
	col = col1 + 14 ;

	for (thread = 0; thread < THREADS; thread++)
		{
		SetCursorPosition(row1, col) ;
		PutString("Thread ") ;
		PutUnsigned(thread + 1, 10, 0) ;
		col += THREAD_SPACING ;
		}

	SetCursorPosition(row += 2, col1) ;
	PutString("Executions:") ;

	SetCursorPosition(row += 2, col1) ;
	PutString("     State:") ;

	for (resource = 0; resource < RESOURCES; resource++)
		{
		SetCursorPosition(row += 2, col1) ;
		PutString("Resource ") ;
		PutUnsigned(resource + 1, 10, 0) ;
		PutString(":") ;
		}

	for (;;)
		{
		static unsigned counter = 0 ;
		static char *states[] =
			{
			"DORMANT ",
			"PENDING ",
			"READY   ",
			"RUNNING ",
			"SLEEPING"
			} ;

		OSSchedLock() ;
		SetCursorPosition(24, 44) ;
		PutUnsigned(++counter, 10, 0) ;

		row = row1 + 2 ;
		col = col1 + 18 ;
		for (thread = 0; thread < THREADS; thread++)
			{
			SetCursorPosition(row, col) ;
			PutUnsigned(executions[thread], 10, 0) ;
			col += THREAD_SPACING ;
			}

		row += 2 ;
		col = col1 + 15 ;
		Analyze() ;
		for (thread = 0; thread < THREADS; thread++)
			{
			SetCursorPosition(row, col) ;
			if (Deadlock(thread)) PutString("DEADLOCK") ;
			else PutString(states[thread_state[thread]]) ;
			col += THREAD_SPACING ;
			}

		for (resource = 0; resource < RESOURCES; resource++)
			{
			row += 2 ;
			col = col1 + 15 ;
			for (thread = 0; thread < THREADS; thread++)
				{
				SetCursorPosition(row, col) ;
				if (acquired[thread][resource])
					PutString("ACQUIRED") ;
				else if (pending[thread][resource])
					PutString("PENDING ") ;
				else
					PutString("        ") ;
				col += THREAD_SPACING ;
				}
			}

		OSSchedUnlock() ;
		OSTimeDly(50) ;
		}
	}

PRIVATE OS_STK *CreateStack(void)
	{
	OS_STK *top = (OS_STK *) malloc(STACK_SIZE) + STACK_SIZE ;
	if (!top) for (;;) ;
	return top ;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -