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

📄 sync.c

📁 一个AVR单片机的操作系统
💻 C
字号:
/** * Copyright (c) 2006-2008 iWESUN (ShenZhen) Inf. * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without modification,  * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  * OF SUCH DAMAGE. * * This file is part of the AvrcX MTOS *  * Author: Winter Hu  <winter.hu@gmail.com> * Create: Nov 27, 2006 */#include "sync.h"#include "scheduler.h"/** * Currently executing task swap out and put into BlockedQueue of  * semaphore */void NAKED asleep(void);/** * Resumes tasks which are ready status from BlockedQueue of semaphore * * @param LinkedList*, The pointer to the BlockedQueue */void wakeup(void);/** * Set value of Semaphore * * @param Semaphore*, The pointer to the Semaphore monitor * @param signed char, The value of semaphore */INTERFACE void set_semaphore(Semaphore* sem, signed char sema){  sem->sema = sema;}/** * Reset Event to un-trigger status * User MUST invoke this method to reset Event monitor after wakeup * * @param Event*, The pointer to the Event monitor * @see void triggerEvent(Event*) */INTERFACE void reset_event(Event* event){  event->sema = 0;}/** * P primitive of the Semaphore * If --sema < 0, the caller will be swaped to BlockedQueue *  * @param Semaphore*, The pointer to the Semaphore */INTERFACE void P(Semaphore* sem){  into_critical();  /* Because Event only has two status fired or unfired */  sem->sema = (sem->type == TYPE_EVENT) ? -1 : sem->sema-1;    if (sem->sema < 0 && (kernel.SysLevel == USER_MODE)){    // TODO: asleep(sem->BlockedQueue);    kernel.BlockedQueue = &(sem->BlockedQueue);    asleep();  }    exit_critical();}/** * V primitive of the Semaphore * If ++sema <= 0, the FIRST process in BlockedQueue will be wakeup * * @param Semaphore*, The pointer to the Semaphore monitor */INTERFACE void V(Semaphore* sem){  into_critical();  /* Because Event only has two status fired or unfired */  sem->sema = (sem->type == TYPE_EVENT) ? 0 : sem->sema+1;  if (sem->sema <= 0){    // TODO: wakeup(sem->BlockedQueue);    kernel.BlockedQueue = &(sem->BlockedQueue);    wakeup();  }    exit_critical();}/** * Release Mutex monitor, the FIRST process in BlockedQueue will be wakeup * * @param Mutex*, The pointer to the Mutex monitor * @see void waitObject(Monitor*) */INTERFACE void release_mutex(Mutex* mutex){  V(mutex);}/** * Trigger Event monitor, ALL processes in BlockedQueue could be wakeup, * User MUST reset Event monitor obviously. * * @param Event*, The pointer to the Event monitor * @see void waitObject(Monitor*) * @see void resetEvent(Event*) */INTERFACE void trigger_event(Event* event){  V(event);}/** * The caller maybe blocked in the BlockedQueue until the monitor object is * obtainable. * * @param Monitor*, The pointer to the Semaphore, Mutex or Event  * @see void V(Semaphore*) * @see void releaseMutex(Mutex*) * @see void triggerEvent(Event*) */INTERFACE void wait_object(Monitor* mon){  P(mon);}/** * The caller blocked in the BlockedQueue until the monitor object is  * obtainable or the specified time is timeout. * * @param Monitor*, The pointer to the Semaphore, Mutex, or Event  * @param unsinged int, The timeout in ticks, 0 is never timeout. * @return unsigned char, 0, the monitor is obtainable. 1, timeout */INTERFACE unsigned char wait_object_with_timeout(Monitor* mon, 					      unsigned int timeout){  into_critical();  PCB* pcb = (PCB*)(kernel.Running->pData);  pcb->timer.ticks = timeout;  P(mon);    // Here, I wakeup  into_critical();  unsigned char status = pcb->status & TASK_BLOCK;  // Because the task in BlockedQueue and TimerQueue, so must remove from  // another queue after wakeup  if (status == 0){    PCB* pcb = (PCB*)(kernel.Running->pData);    remove(&(kernel.TimerQueue), &(pcb->tid));  }else{    remove(&(mon->BlockedQueue), kernel.Running);    status = 1;  }  exit_critical();  return status;}/** * Currently executing task swap out and put into BlockedQueue of  * semaphore */void asleep(void){  prologue();    PID* pid = kernel.Running;  PCB* pcb = (PCB*)(pid->pData);  // PID to TimerQueue  if (pcb->timer.ticks > 0){    delay_task(pid, pcb->timer.ticks);  }  // PID to BlockedQueue  pcb->status |= TASK_BLOCK;  append(kernel.BlockedQueue, pid);  swapping();    epilogue();}/** * Resumes tasks which are ready status from BlockedQueue of semaphore * * @see resumeTask * @param LinkedList*, The pointer to the BlockedQueue */void wakeup(void){  PID* pid = remove_first(kernel.BlockedQueue);  if (pid == NULL) return;  PCB* pcb = (PCB*)(pid->pData);  pcb->status &= ~TASK_BLOCK;      if(kernel.SysLevel != USER_MODE){    // Already in kernel    if (kernel.Running != NULL){      if (pcb->priority < ((PCB*)(kernel.Running->pData))->priority){	// Preemptived	resume_task(kernel.Running);      }    }    kernel.Running = pid;    kernel.TmSlices= pcb->tmslices;  }else{    // USER_MODE    resume_task(pid);  }}

⌨️ 快捷键说明

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