예제 #1
0
파일: cpu.c 프로젝트: DuyH/TCSS422
void CPU_scheduler(CPU_p cpu, Interrupt_type interrupt_type, int PC) {
    while (!Queue_isEmpty(cpu->newProcessesQueue)) {
        PCB_p temp_pcb = Queue_dequeue(cpu->newProcessesQueue);
        PCB_set_state(temp_pcb, ready);
        //PCB_set_pc(temp_pcb, PC);
        Queue_enqueue(cpu->readyQueue, temp_pcb);
        fprintf(file, "Process ID: %u Enqueued\n", temp_pcb->pid);
        fprintf(file, "%s", PCB_toString(temp_pcb));
    }
    fprintf(file, "\n");
    switch (interrupt_type) {
        case timer:
            // 1. Put process back into the readyQueue
            Queue_enqueue(cpu->readyQueue, cpu->currentProcess);

            // 2. Change its state from interrupted to ready
            PCB_set_state(cpu->currentProcess, ready);

            // 3. Make call to dispatcher
            CPU_dispatcher(cpu, timer);

            // 4. Returned from dispatcher, do any housekeeping
            // Nothing here to do at the moment!

            // 5. Returns to pseudo-ISR
            return;
            break;
        default:
            CPU_dispatcher(cpu, normal);
            break;
    }
    return;
}
예제 #2
0
void bfs(BFSVertex* vertices, int nelem, int s) {
	Queue q;
	for (int u = 0; u < nelem; u++) {
		if (vertices[u].super.n != s) {
			vertices[u].super.color = WHITE;
			vertices[u].d = 1E10;
			vertices[u].super.parent = -1;
		}
	}
	vertices[s].super.color = GRAY;
	vertices[s].d = 0;
	vertices[s].super.parent = -1;
	Queue_init(&q);
	Queue_create_queue(&q, nelem);
	Queue_enqueue(&q, s);
	while (!Queue_is_empty(&q)) {
		int u = Queue_dequeue(&q);
		for (Adj* adj_v = vertices[u].super.first; adj_v; adj_v = adj_v->next) {
			if (vertices[adj_v->n].super.color == WHITE) {
				vertices[adj_v->n].super.color = GRAY;
				vertices[adj_v->n].d = vertices[u].d + 1;
				vertices[adj_v->n].super.parent = u;
				Queue_enqueue(&q, adj_v->n);
			}
		}
		vertices[u].super.color = BLACK;
	}
}
예제 #3
0
파일: queue_test.c 프로젝트: yksz/c-sclib
static int test_enqueue()
{
    Queue* queue = Queue_new(0);
    int array[] = {1, 2, 3};
    Queue_enqueue(queue, &array[0]);
    Queue_enqueue(queue, &array[1]);
    Queue_enqueue(queue, &array[2]);
    nu_assert_eq_int(3, Queue_size(queue));
    Queue_free(queue);
    return 0;
}
예제 #4
0
파일: queue_test.c 프로젝트: yksz/c-sclib
static int test_capacity()
{
    Queue* queue = Queue_new(2);
    int array[] = {1, 2, 3};
    nu_assert(Queue_enqueue(queue, &array[0]));
    nu_assert(Queue_enqueue(queue, &array[1]));
    nu_assert(!Queue_enqueue(queue, &array[2]));
    Queue_dequeue(queue);
    nu_assert(Queue_enqueue(queue, &array[2]));
    Queue_free(queue);
    return 0;
}
예제 #5
0
int main(void) {
    const int MAX_QUEUE_SIZE = 7;
    Queue_t queue = Queue_new();
    const char * dllName = userChoice();
    dynamic_t * dll = dynamic_init(dllName);
    if (NULL == dll) {
        printf("Can't load dynamic!\n");
        return 1;
    }
    if (NULL == dll->check) {
        printf("Can't get compare function!\n");
        return 1;
    }
    if (NULL == dll->react) {
        printf("Can't get reaction function!\n");
        return 1;
    }
    puts("Dynamic loaded!");
    srand(time(NULL));
    for (int i = 0; i < MAX_QUEUE_SIZE; i++) {
        int prec =  !(rand() % 3) ? 1 + rand() % 15 : 0;
        printf("%dth day's precipitation: %d\n", i, prec);
        Queue_enqueue(queue, prec);
    }
    if(dll->check(queue))
        dll->react();
    Queue_delete(queue);
    return 0;
}
예제 #6
0
/*
 *  ======== Task_unblockI ========
 *  Unblock a task.
 *
 *  Place task in its ready list.
 *  Must be called within Task_disable/Task_restore block
 *  and with interrupts disabled
 */
Void Task_unblockI(Task_Object *tsk, UInt hwiKey)
{
#ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS
    Int i;
#endif
    UInt curset = Task_module->curSet;
    UInt mask = tsk->mask;

    Queue_enqueue(tsk->readyQ, (Queue_Elem *)tsk);

    Task_module->curSet = curset | mask;
    tsk->mode = Task_Mode_READY;
    Task_module->workFlag = 1;

    /* It's safe to enable intrs here */
    Hwi_restore(hwiKey);

#ifndef ti_sysbios_knl_Task_DISABLE_ALL_HOOKS
    for (i = 0; i < Task_hooks.length; i++) {
        if (Task_hooks.elem[i].readyFxn != NULL) {
            Task_hooks.elem[i].readyFxn(tsk);
        }
    }
#endif

    Log_write3(Task_LD_ready, (UArg)tsk, (UArg)tsk->fxn, (UArg)tsk->priority);

    /* Hard-disable intrs - this fxn is called with them disabled */
    Hwi_disable();
}
예제 #7
0
// parse a recieved byte stream for packets
void Packets_rxCallback(char* rx, uint8_t length){
	
	length -= PACKETS_TERMINATOR_LEN;
	uint8_t crc_high = length-2;
	uint8_t crc_low = length-1;
	
	Packet packet;
	packet.crc = 0;
	packet.length = length-3;

	for (uint8_t i = 0; i < length; i++){
		if (i == 0) packet.address = rx[i]; 
		else if (i == crc_high){
			packet.crc = rx[i]; 
			packet.crc = packet.crc << 8 ; 
		}
		else if (i == crc_low) packet.crc += rx[i];
		else packet.data[i-1] = rx[i]; 
	}

		
	// check crc
	uint16_t crc = crc16(rx, length-2);
	if (crc != packet.crc){
		Packets_setError(PACKETS_ERR_CRC);
		return;
	}
	
	

	Queue* queue; 
	queue = Packets_getQueue();
	Queue_enqueue(queue, &packet);

}
예제 #8
0
/*******************************************************************************
 * @fn      SensorTag_processOadWriteCB
 *
 * @brief   Process a write request to the OAD profile.
 *
 * @param   event      - event type:
 *                       OAD_WRITE_IDENTIFY_REQ
 *                       OAD_WRITE_BLOCK_REQ
 * @param   connHandle - the connection Handle this request is from.
 * @param   pData      - pointer to data for processing and/or storing.
 *
 * @return  None.
 */
static void SensorTag_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                           uint8_t *pData)
{
  oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                             sizeof(uint8_t) * OAD_PACKET_SIZE);

  if ( oadWriteEvt != NULL )
  {
    oadWriteEvt->event = event;
    oadWriteEvt->connHandle = connHandle;

    oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
    memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);

    Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt);

    // Post the application's semaphore.
    Semaphore_post(sem);
  }
  else
  {
    // Fail silently.
  }

}
예제 #9
0
// -----------------------------------------------------------------------------
//! \brief   Creates a queue node and puts the node in RTOS queue.
//!
//! \param   msgQueue - queue handle.
//! \param   sem - thread's event processing semaphore that queue is
//!                associated with.
//! \param   pMsg - pointer to message to be queued
//!
//! \return  TRUE if message was queued, FALSE otherwise.
// -----------------------------------------------------------------------------
uint8_t NPIUtil_enqueueMsg(Queue_Handle msgQueue, Semaphore_Handle sem,
                           uint8_t *pMsg)
{
  queueRec_t *pRec;
  
  // Allocated space for queue node.
  if (pRec = NPIUTIL_MALLOC(sizeof(queueRec_t)))
  {
    pRec->pData = pMsg;
  
    Queue_enqueue(msgQueue, &pRec->_elem);
    
    // Wake up the application thread event handler.
    if (sem)
    {
      Semaphore_post(sem);
    }
    
    return TRUE;
  }
  
  // Free the message.
  NPIUTIL_FREE(pMsg);
  
  return FALSE;
}
예제 #10
0
파일: GIO.c 프로젝트: andreimironenko/bios
/*
 *  ======== GIO_reclaim ========
 */
Int GIO_reclaim(GIO_Object *obj, Ptr *pBuf, SizeT *pSize, UArg *pArg)
{
    IOM_Packet          *packet;
    Queue_Handle        doneList;
    Queue_Handle        freeList;
    UInt                key;
    Int                 status;
    Error_Block         eb;
    
    doneList = GIO_Instance_State_doneList(obj);
    freeList = GIO_Instance_State_freeList(obj);

    Error_init(&eb);

    while (obj->doneCount == 0) {
        if (Sync_wait(obj->sync, obj->timeout, &eb) == 
                Sync_WaitStatus_TIMEOUT) {

            return (IOM_ETIMEOUT);
        }
    }

    key = Hwi_disable();
    obj->doneCount--;
    packet = Queue_dequeue(doneList);
    Hwi_restore(key);

    if (pArg != NULL) {
        *pArg = packet->arg;
    }

    /* pBuf is set to NULL by GIO_read() and GIO_write() */
    if (pBuf != NULL) {
        *pBuf = packet->addr;
    }

    if (pSize != NULL) {
        *pSize = packet->size;
    }

    status = packet->status;

    /* 
     * re-signal if more buffers are ready
     * This is required in the case of ISyncEvent and ISyncSwi to allow 
     * clients to reclaim a single buffer and not force them to bleed the 
     * stream.
     */
    if (obj->doneCount > 0) {
        Sync_signal(obj->sync);
    }

    /* recycle packet back onto free list */
    key = Hwi_disable();
    obj->freeCount++;
    Queue_enqueue(freeList, (Queue_Elem *)packet);
    Hwi_restore(key);

    return (status);
}
예제 #11
0
파일: queue_test.c 프로젝트: yksz/c-sclib
static int test_front_back()
{
    Queue* queue = Queue_new(0);
    nu_assert_eq_ptr(NULL, Queue_front(queue));
    nu_assert_eq_ptr(NULL, Queue_back(queue));

    int array[] = {1, 2, 3};
    Queue_enqueue(queue, &array[0]);
    Queue_enqueue(queue, &array[1]);
    Queue_enqueue(queue, &array[2]);
    nu_assert_eq_ptr(&array[0], Queue_front(queue));
    nu_assert_eq_ptr(&array[2], Queue_back(queue));
    nu_assert_eq_int(3, Queue_size(queue));
    Queue_free(queue);
    return 0;
}
예제 #12
0
/*********************************************************************
 * @fn      Util_enqueueMsg
 *
 * @brief   Creates a queue node and puts the node in RTOS queue.
 *
 * @param   msgQueue - queue handle.
 * @param   sem - thread's event processing semaphore that queue is
 *                associated with.
 * @param   pMsg - pointer to message to be queued
 *
 * @return  TRUE if message was queued, FALSE otherwise.
 */
uint8_t Util_enqueueMsg(Queue_Handle msgQueue, Semaphore_Handle sem,
                        uint8_t *pMsg)
{
  queueRec_t *pRec;
  
  // Allocated space for queue node.
#ifdef USE_ICALL
  if (pRec = ICall_malloc(sizeof(queueRec_t)))
#else
  if (pRec = (queueRec_t *)malloc(sizeof(queueRec_t)))
#endif
  {
    pRec->pData = pMsg;
  
    Queue_enqueue(msgQueue, &pRec->_elem);
    
    // Wake up the application thread event handler.
    if (sem)
    {
      Semaphore_post(sem);
    }
    
    return TRUE;
  }
  
  // Free the message.
#ifdef USE_ICALL
  ICall_free(pMsg);
#else
  free(pMsg);
#endif
  
  return FALSE;
}
예제 #13
0
int main()
{
//    moduleTests_Queue();
    Queue_t queue1 = Queue_new();
    Queue_t queue2 = Queue_new();

    for(int i = 0; i < 10; i++){
        Queue_enqueue(queue1, randInt());
        Queue_enqueue(queue2, randInt());
    }

    Queue_bindQueues(queue1, queue2);

    Queue_subscribeSingleOverflowEvent(queue1, singleQueueOverflow1, "queue1");
    Queue_subscribeSingleOverflowEvent(queue1, singleQueueOverflow2, "queue1");

    Queue_subscribeSingleOverflowEvent(queue2, singleQueueOverflow1, "queue2");
    Queue_subscribeSingleOverflowEvent(queue2, singleQueueOverflow2, "queue2");

    Queue_subscribePairOverflowEvent(queue1, queuePairOverflow, "queue1");
    Queue_subscribePairEmptyEvent(queue1, queuePairEmpty, "queue1");

    Queue_subscribePairOverflowEvent(queue2, queuePairOverflow, "queue2");
    Queue_subscribePairEmptyEvent(queue2, queuePairEmpty, "queue2");

    for(int i = 0; i < 50; i++){
        int rndInt = randInt();
        if(randBool()){
            if(rndInt >= 0){
                Queue_enqueue(queue1, rndInt);
            }else{
                Queue_dequeue(queue1);
            }
        }else{
            if(rndInt >= 0){
                Queue_enqueue(queue2, rndInt);
            }else{
                Queue_dequeue(queue2);
            }
        }
    }

    Queue_delete(queue1);
    Queue_delete(queue2);
    return 0;
}
예제 #14
0
파일: GIO.c 프로젝트: andreimironenko/bios
/*
 *  ======== callback ========
 *  This function is called by the underlying IOM driver.
 */
static Void callback(Ptr cbArg, IOM_Packet *packet)
{
    GIO_Handle       obj = (GIO_Handle)cbArg;
    GIO_AppCallback  *appCallback = (GIO_AppCallback *)packet->misc;
    Int              status;
    Ptr              addr;
    SizeT            size;
    Queue_Handle     list;
    UInt             key;

    key = Hwi_disable();
    obj->submitCount--;
    Hwi_restore(key);

    if (appCallback == NULL) {
        Sync_signal(obj->sync);
    }
    else {
        if (obj->model == GIO_Model_ISSUERECLAIM) {
            /* put packet on doneList where GIO_reclaim() will find it */
            list = GIO_Instance_State_doneList(obj);
    
            key = Hwi_disable();
            obj->doneCount++;
            Queue_enqueue(list, (Queue_Elem *)packet);
            Hwi_restore(key);

            Sync_signal(obj->sync);
        }
        else {
            list = GIO_Instance_State_freeList(obj);

            status = packet->status; 
            addr = packet->addr;
            size = packet->size;    

            key = Hwi_disable();
            obj->freeCount++;
            Queue_enqueue(list, (Queue_Elem *)packet);
            Hwi_restore(key);

            (*appCallback->fxn)(appCallback->arg, status, addr, size);
        }
    }
}
예제 #15
0
파일: cpu.c 프로젝트: DuyH/TCSS422
/**
 * Function that creates 0-5 new processes and puts them into a list.
 */
Queue *CPU_create_processes(Queue *queue, int numb_process, int process_ID) {
    int n;
    for (n = 0; n < numb_process; n++) {
        PCB *pcb = PCB_constructor();
        PCB_set_pid(pcb, process_ID + n);
        PCB_set_priority(pcb, rand() % 31 + 1);
        PCB_set_state(pcb, created);
        queue = Queue_enqueue(queue, pcb);
    }
    return queue;
}
예제 #16
0
//parser enqueues
void *enq_helper(void* argPtr)
{
	Queue_enqueue(((EPacket_t*)(argPtr))->x, ((EPacket_t*)(argPtr))->q, ((EPacket_t*)(argPtr))->queue_size);
	printf("%d: enqueuehelper getting mainmutex\n", pthread_self());
	pthread_mutex_lock(&mainMutex);
	printf("%d: enqueuehelper got mainmutex, ++work; workInSystem = %d \n", pthread_self(), workInSystem);
	workInSystem++;
	printf("%d: enqueuehelper going to release mainmutex; workInSystem = %d \n", pthread_self(), workInSystem);
	pthread_mutex_unlock(&mainMutex);
	printf("%d: enqueuehelper released mainmutex\n", pthread_self());
}
예제 #17
0
/*
 *  ======== Swi_post ========
 */
Void Swi_post(Swi_Object *swi)
{
    UInt hwiKey;
    UInt swiKey;
#ifndef ti_sysbios_knl_Swi_DISABLE_ALL_HOOKS
    Int i;
#endif

    Log_write3(Swi_LM_post, (UArg)swi, (UArg)swi->fxn, (UArg)swi->priority);

    hwiKey = Hwi_disable();

    if (swi->posted) {
        Hwi_restore(hwiKey);
        return;
    }

    swi->posted = TRUE;

    swiKey = Swi_disable();

    /* Place the Swi in the appropriate ready Queue. */
    Queue_enqueue(swi->readyQ, (Queue_Elem *)swi);

    /* Add this priority to current set */
    Swi_module->curSet |= swi->mask;

    Hwi_restore(hwiKey);  /* Not in FIFO order. OK! */

#ifndef ti_sysbios_knl_Swi_DISABLE_ALL_HOOKS
    /*
     * This hook location supports the STS "set ready time" operation on
     * Swis.  This is equivalent to pre-BIOS 6.
     */
    for (i = 0; i < Swi_hooks.length; i++) {
        if (Swi_hooks.elem[i].readyFxn != NULL) {
            Swi_hooks.elem[i].readyFxn(swi);
        }
    }
#endif

    /* 
     * Modified Swi_restore().
     * No need to check curSet since we just set it.
     */
    if (swiKey == FALSE) {
        if (Core_getId() == 0) {
            Swi_schedule(); /* unlocks Swi scheduler on return */
        }
        else {
            Swi_restoreSMP(); /* interrupt core 0 to do the work */
        }
    }
}
예제 #18
0
파일: queue_test.c 프로젝트: yksz/c-sclib
static int test_size()
{
    Queue* queue = Queue_new(0);
    nu_assert_eq_int(0, Queue_size(queue));

    int array[] = {1};
    Queue_enqueue(queue, &array[0]);
    nu_assert_eq_int(1, Queue_size(queue));
    Queue_dequeue(queue);
    nu_assert_eq_int(0, Queue_size(queue));
    Queue_free(queue);
    return 0;
}
예제 #19
0
파일: queue_test.c 프로젝트: yksz/c-sclib
static int test_empty()
{
    Queue* queue = Queue_new(0);
    nu_assert(Queue_empty(queue));

    int array[] = {1};
    Queue_enqueue(queue, &array[0]);
    nu_assert(!Queue_empty(queue));
    Queue_dequeue(queue);
    nu_assert(Queue_empty(queue));
    Queue_free(queue);
    return 0;
}
예제 #20
0
/*
 *  ======== Task_yield ========
 */
Void Task_yield()
{
    UInt tskKey, hwiKey;

    tskKey = Task_disable();
    hwiKey = Hwi_disable();

    if (Task_module->curQ) {
        /* move current task to end of curQ */
        Queue_enqueue(Task_module->curQ,
            Queue_dequeue(Task_module->curQ));
    }
    Task_module->curQ = NULL;  /* force a Task_switch() */
    Task_module->workFlag = 1;

    Hwi_restore(hwiKey);

    Log_write3(Task_LM_yield, (UArg)Task_module->curTask, (UArg)(Task_module->curTask->fxn), (UArg)(BIOS_getThreadType()));

    Task_restore(tskKey);
}
// -----------------------------------------------------------------------------
//! \brief   Creates a queue node and puts the node in RTOS queue.
//!
//! \param   msgQueue - queue handle.
//! \param   event - thread's event processing synchronization object that
//!                  queue is associated with.
//! \param   eventFlag - events to signal with synchronization object associated
//!                      with this pMsg.
//! \param   sem - thread's event processing semaphore that queue is
//!                associated with.
//! \param   pMsg - pointer to message to be queued
//!
//! \return  TRUE if message was queued, FALSE otherwise.
// -----------------------------------------------------------------------------
uint8_t NPIUtil_enqueueMsg(Queue_Handle msgQueue, 
#ifdef ICALL_EVENTS
                           Event_Handle event,
                           uint32_t eventFlags,
#else //!ICALL_EVENTS
                           Semaphore_Handle sem,
#endif //ICALL_EVENTS
                           uint8_t *pMsg)
{
  queueRec_t *pRec;
  
  // Allocated space for queue node.
  if (pRec = NPIUTIL_MALLOC(sizeof(queueRec_t)))
  {
    pRec->pData = pMsg;
  
    Queue_enqueue(msgQueue, &pRec->_elem);
    
    // Wake up the application thread event handler.
#ifdef ICALL_EVENTS
    if (event)
    {
      Event_post(event, eventFlags);
    }
#else //!ICALL_EVENTS
    if (sem)
    {
      Semaphore_post(sem);
    }
#endif //ICALL_EVENTS
    
    return TRUE;
  }
  
  // Free the message.
  NPIUTIL_FREE(pMsg);
  
  return FALSE;
}
예제 #22
0
/*
 *  ======== GateMutexPri_insertPri ========
 *  Inserts the element in order by priority, with higher priority
 *  elements at the head of the queue.
 */
Void GateMutexPri_insertPri(Queue_Object* queue, Queue_Elem* newElem, Int newPri)
{
    Queue_Elem* qelem;
    
    /* Iterate over the queue. */
    for (qelem = Queue_head(queue); qelem != (Queue_Elem *)queue; 
         qelem = Queue_next(qelem)) {
        /* Tasks of equal priority will be FIFO, so '>', not '>='. */
        if (newPri > Task_getPri((Task_Handle)qelem)) {
            /* Place the new element in front of the current qelem. */
            Queue_insert(qelem, newElem);
            return;
        }
    }
    
    /*
     * Put the task at the back of the queue if:
     *   1. The queue was empty.
     *   2. The task had the lowest priority in the queue.
     */
    Queue_enqueue(queue, newElem);
}
예제 #23
0
파일: cpu.c 프로젝트: DuyH/TCSS422
Queue_p CPU_enqueue_terminatedQueue(CPU_p cpu, PCB_p pcb) {
    return Queue_enqueue(CPU_get_terminatedQueue(cpu), pcb);
}
예제 #24
0
파일: GIO.c 프로젝트: andreimironenko/bios
/*
 *  ======== GIO_submit ========
 */
Int GIO_submit(GIO_Object *obj, Uns cmd, Ptr buf, 
        SizeT *pSize, GIO_AppCallback *appCallback)
{
    IOM_Packet      syncPacket;
    IOM_Packet      *packet;
    SizeT           nullSize; 
    Int             status;
    UInt            key;
    Queue_Handle    list;
    Error_Block     eb;
    IOM_Fxns        *iomFxns;

    iomFxns = (IOM_Fxns *)obj->fxns;

    if (appCallback == NULL) {
        packet = &syncPacket;
    }
    else {
        list = GIO_Instance_State_freeList(obj);

        if (obj->freeCount == 0) { 
            return (IOM_ENOPACKETS);
        }

        key = Hwi_disable();
        obj->freeCount--;
        packet = Queue_dequeue(list);
        Hwi_restore(key);
    }

    if (pSize == NULL) {
        nullSize = 0;
        pSize = &nullSize;
    }

    packet->cmd = cmd;
    packet->addr = buf;
    packet->size = *pSize;
    packet->status = IOM_COMPLETED;

    /*
     * 'appCallback' will be NULL for synchronous calls.
     * 'packet->misc' is used in the callback to call asynch callback
     * or post semaphore (sync).
     */
    packet->misc = (UArg)appCallback;

    status = iomFxns->mdSubmitChan(obj->mdChan, packet);

    if ((status == IOM_COMPLETED) || (status < 0)) {
        if (status == IOM_COMPLETED) {
            *pSize = packet->size;
            status = packet->status;
        }

        /* if asynch, put packet back on freeList */
        if (appCallback != NULL) {
            key = Hwi_disable();
            obj->freeCount++;
            Queue_enqueue(list, (Queue_Elem *)packet);
            Hwi_restore(key);
        }

        return (status);
    }

    /* 
     * call Sync_wait only if synchronous I/O and mdSubmitChan did not
     * return an error (status < 0)
     */
    if (appCallback == NULL) {
        Error_init(&eb);

        if (Sync_wait(obj->sync, obj->timeout, &eb) == 
                Sync_WaitStatus_SUCCESS) {
            *pSize = packet->size;
            status = packet->status;
        }
        else {
            *pSize = 0; 

            /*
             * NOTE: A channel timeout needs special handling. Timeouts are
             * usually due to some serious underlying device or system state
             * and may require the channel, or possibly the device,to be reset.
             * Because the mini-driver may still own the IOM_Packet here
             * driver's will need to perform timeout processing. We will call
             * the mini-driver's control fxn with the IOM_CHAN_TIMEDOUT command
             * code.
             */
            status = iomFxns->mdControlChan(obj->mdChan, 
                IOM_CHAN_TIMEDOUT, NULL);

            if (status != IOM_COMPLETED) {
                return (IOM_ETIMEOUTUNREC);  /* fatal, may have lost packet */
            }

            return (IOM_ETIMEOUT);
        }
    }

    return (status);
}
예제 #25
0
파일: GIO.c 프로젝트: andreimironenko/bios
/*
 *  ======== GIO_Instance_init ========
 */
Int GIO_Instance_init(GIO_Object *obj, String name, UInt mode,
    const GIO_Params *params, Error_Block *eb)
{
    Int                 i, status;
    Queue_Handle        doneList;
    Queue_Handle        freeList;
    DEV_Handle          device;
    IOM_Packet          *packets;
    IOM_Fxns            *iomFxns;
    Ptr                 devp;
    
    obj->name = name;
    obj->numPackets = params->numPackets;
    obj->doneCount = 0;
    obj->freeCount = 0;
    obj->submitCount = 0;
    obj->mode = mode;
    obj->model = params->model;
    obj->timeout = params->timeout;

    if (params->sync == NULL) {       
        obj->userSync = FALSE;
        obj->sync = SyncSemThread_Handle_upCast(SyncSemThread_create(NULL, eb));
        if (obj->sync == NULL) {
            return (1);
        }
    }
    else {
        obj->sync = params->sync;
        obj->userSync = TRUE;
    }

    doneList = GIO_Instance_State_doneList(obj);
    Queue_construct(Queue_struct(doneList), NULL);
    
    freeList = GIO_Instance_State_freeList(obj);
    Queue_construct(Queue_struct(freeList), NULL);
    
    /* allocate packets */
    packets = Memory_alloc(NULL, sizeof(IOM_Packet) * (obj->numPackets), 0, eb);

    if (packets == NULL) {
        return (2);
    }

    obj->packets = packets;
    obj->freeCount = obj->numPackets;
   
    /* 
     * Split the buffer into packets and add to freeList
     */
    for (i = 0; i < obj->numPackets; i++) {
        Queue_enqueue(freeList, (Queue_Elem *)&packets[i]);
    }
    
    name = DEV_match(name, &device);    
        
    if (device == NULL) {
        /* The name was not found */
        Error_raise(eb, GIO_E_notFound, obj->name, 0);
        return (3);
    }

    obj->fxns = DEV_getFxns(device);
    iomFxns = (IOM_Fxns *)obj->fxns;       

    devp = DEV_getDevp(device);

    status = iomFxns->mdCreateChan(&obj->mdChan, devp, name, mode,
        params->chanParams, callback, obj);
  
    if (status != IOM_COMPLETED) {
        Error_raise(eb, GIO_E_createFailed, status, 0);
        return (4);
    }
    
    return (0);
}
예제 #26
0
/*
 *  ======== Event_pend ========
 */
UInt Event_pend(Event_Object *event, UInt andMask, UInt orMask, UInt32 timeout)
{
    UInt hwiKey, tskKey;
    Event_PendElem elem;
    UInt matchingEvents;
    Queue_Handle pendQ;
    Clock_Struct clockStruct;

    Assert_isTrue(((andMask | orMask) != 0), Event_A_nullEventMasks);

    Log_write5(Event_LM_pend, (UArg)event, (UArg)event->postedEvents,
                (UArg)andMask, (UArg)orMask, (IArg)((Int)timeout));

    /*
     * elem is filled in entirely before interrupts are disabled.
     * This significantly reduces latency at the potential cost of wasted time
     * if it turns out that there is already an event match.
     */

    /* add Clock event if timeout is not FOREVER nor NO_WAIT */
    if (BIOS_clockEnabled
            && (timeout != BIOS_WAIT_FOREVER)
            && (timeout != BIOS_NO_WAIT)) {
        Clock_addI(Clock_handle(&clockStruct), (Clock_FuncPtr)Event_pendTimeout, timeout, (UArg)&elem);
        elem.tpElem.clock = Clock_handle(&clockStruct);
        elem.pendState = Event_PendState_CLOCK_WAIT;
    }
    else {
        elem.tpElem.clock = NULL;
        elem.pendState = Event_PendState_WAIT_FOREVER;
    }

    /* fill in this task's Event_PendElem */
    elem.andMask = andMask;
    elem.orMask = orMask;

    pendQ = Event_Instance_State_pendQ(event);

    /* get task handle */
    elem.tpElem.task = Task_self();

    /* Atomically check for a match and block if none */
    hwiKey = Hwi_disable();

    /* check if events are already available */
    matchingEvents = Event_checkEvents(event, andMask, orMask);

    if (matchingEvents != 0) {
        /* remove Clock object from Clock Q */
        if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) {
            Clock_removeI(elem.tpElem.clock);
            elem.tpElem.clock = NULL;
        }

        Hwi_restore(hwiKey);

        return (matchingEvents);/* yes, then return with matching bits */
    }

    if (timeout == BIOS_NO_WAIT) {
        Hwi_restore(hwiKey);
        return (0);             /* No match, no wait */
    }

    Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task),
                        Event_A_badContext);

    /*
     * Verify that THIS core hasn't already disabled the scheduler
     * so that the Task_restore() call below will indeed block
     */
    Assert_isTrue((Task_enabled()),
                        Event_A_pendTaskDisabled);

    /* lock scheduler */
    tskKey = Task_disable();

    /* only one Task allowed!!! */
    Assert_isTrue(Queue_empty(pendQ), Event_A_eventInUse);

    /* leave a pointer for Task_delete() */
    elem.tpElem.task->pendElem = (Task_PendElem *)&(elem);

    /* add it to Event_PendElem queue */
    Queue_enqueue(pendQ, (Queue_Elem *)&elem);

    Task_blockI(elem.tpElem.task);

    if (BIOS_clockEnabled &&
            (elem.pendState == Event_PendState_CLOCK_WAIT)) {
        Clock_startI(elem.tpElem.clock);
    }

    Hwi_restore(hwiKey);

    /* unlock task scheduler and block */
    Task_restore(tskKey);       /* the calling task will switch out here */

    /* Here on unblock due to Event_post or Event_pendTimeout */

    hwiKey = Hwi_disable();

    /* remove Clock object from Clock Q */
    if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) {
        Clock_removeI(elem.tpElem.clock);
        elem.tpElem.clock = NULL;
    }
        
    elem.tpElem.task->pendElem = NULL;

    Hwi_restore(hwiKey);
    
    /* event match? */
    if (elem.pendState != Event_PendState_TIMEOUT) {
        return (elem.matchingEvents);
    }
    else {
        return (0);             /* timeout */
    }
}
예제 #27
0
파일: cpu.c 프로젝트: DuyH/TCSS422
Queue_p CPU_enqueue_readyQueue(CPU_p cpu, PCB_p pcb) {
    return Queue_enqueue(CPU_get_readyQueue(cpu), pcb);
}
예제 #28
0
/*
 *  ======== Semaphore_pend ========
 */
Bool Semaphore_pend(Semaphore_Object *sem, UInt timeout)
{
    UInt hwiKey, tskKey;
    Semaphore_PendElem elem;
    Queue_Handle pendQ;
    Clock_Struct clockStruct;

    Log_write3(Semaphore_LM_pend, (IArg)sem, (UArg)sem->count, (IArg)((Int)timeout));

    /*
     *  Consider fast path check for count != 0 here!!!
     */

    /* 
     *  elem is filled in entirely before interrupts are disabled.
     *  This significantly reduces latency.
     */

    /* add Clock event if timeout is not FOREVER nor NO_WAIT */
    if (BIOS_clockEnabled
            && (timeout != BIOS_WAIT_FOREVER) 
            && (timeout != BIOS_NO_WAIT)) {
        Clock_Params clockParams;
        Clock_Params_init(&clockParams);
        clockParams.arg = (UArg)&elem;
        clockParams.startFlag = FALSE;  /* will start when necessary, thankyou */
        Clock_construct(&clockStruct, (Clock_FuncPtr)Semaphore_pendTimeout, 
                                        timeout, &clockParams);
        elem.tpElem.clock = Clock_handle(&clockStruct);
        elem.pendState = Semaphore_PendState_CLOCK_WAIT;
    }
    else {
        elem.tpElem.clock = NULL;
        elem.pendState = Semaphore_PendState_WAIT_FOREVER;
    }

    pendQ = Semaphore_Instance_State_pendQ(sem);

    hwiKey = Hwi_disable();

    /* check semaphore count */
    if (sem->count == 0) {

        if (timeout == BIOS_NO_WAIT) {
            Hwi_restore(hwiKey);
            return (FALSE);
        }

        Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task),
                        Semaphore_A_badContext);

        /* lock task scheduler */
        tskKey = Task_disable();

        /* get task handle and block tsk */
        elem.tpElem.task = Task_self();

        /* leave a pointer for Task_delete() */
        elem.tpElem.task->pendElem = (Task_PendElem *)&(elem);

        Task_blockI(elem.tpElem.task);

        if (((UInt)sem->mode & 0x2) != 0) {    /* if PRIORITY bit is set */
            Semaphore_PendElem *tmpElem;
            Task_Handle tmpTask;
            UInt selfPri;
            
            tmpElem = Queue_head(pendQ);
            selfPri = Task_getPri(elem.tpElem.task);

            while (tmpElem != (Semaphore_PendElem *)pendQ) {
                tmpTask = tmpElem->tpElem.task;
                /* use '>' here so tasks wait FIFO for same priority */
                if (selfPri > Task_getPri(tmpTask)) {
                    break;
                }
                else {
                    tmpElem = Queue_next((Queue_Elem *)tmpElem);
                }
            }
            
            Queue_insert((Queue_Elem *)tmpElem, (Queue_Elem *)&elem);
        }
        else {      
            /* put task at the end of the pendQ */
            Queue_enqueue(pendQ, (Queue_Elem *)&elem);
        }

        /* start Clock if appropriate */
        if (BIOS_clockEnabled && 
                (elem.pendState == Semaphore_PendState_CLOCK_WAIT)) {
            Clock_startI(elem.tpElem.clock);
        }

        Hwi_restore(hwiKey);

        Task_restore(tskKey);   /* the calling task will block here */

        /* Here on unblock due to Semaphore_post or timeout */

        if (Semaphore_supportsEvents && (sem->event != NULL)) {
            /* synchronize Event state */
            hwiKey = Hwi_disable();
            Semaphore_eventSync(sem->event, sem->eventId, sem->count);
            Hwi_restore(hwiKey);
        }

        /* deconstruct Clock if appropriate */
        if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) {
            Clock_destruct(Clock_struct(elem.tpElem.clock));
        }

        elem.tpElem.task->pendElem = NULL;

        return ((Bool)(elem.pendState));
    }
    else {
        --sem->count;

        if (Semaphore_supportsEvents && (sem->event != NULL)) {
            /* synchronize Event state */
            Semaphore_eventSync(sem->event, sem->eventId, sem->count);
        }

        Hwi_restore(hwiKey);

        /* deconstruct Clock if appropriate */
        if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) {
            Clock_destruct(Clock_struct(elem.tpElem.clock));
        }

        return (TRUE);
    }
}
예제 #29
0
/*
 *  ======== Task_setPri ========
 */
UInt Task_setPri(Task_Object *tsk, Int priority)
{
    Int oldPri;
    UInt newMask, tskKey, hwiKey;
    Queue_Handle newQ;

    Assert_isTrue((((priority == -1) || (priority > 0) ||
                  ((priority == 0 && Task_module->idleTask == NULL))) &&
                   (priority < (Int)Task_numPriorities)),
                   Task_A_badPriority);

    Log_write4(Task_LM_setPri, (UArg)tsk, (UArg)tsk->fxn,
                       (UArg)tsk->priority, (UArg)priority);

    tskKey = Task_disable();
    hwiKey = Hwi_disable();

    oldPri = tsk->priority;

    if (oldPri == priority) {
        Hwi_restore(hwiKey);
        Task_restore(tskKey);
        return (oldPri);
    }

    if (priority < 0) {
        newMask = 0;
        newQ = Task_Module_State_inactiveQ();
    }
    else {
        newMask = 1 << priority;
        newQ = (Queue_Handle)((UInt8 *)(Task_module->readyQ) +
                (UInt)(priority*(2*sizeof(Ptr))));
    }

    if (tsk->mode == Task_Mode_READY) {
        Queue_remove((Queue_Elem *)tsk);

        /* if last task in readyQ, remove corresponding bit in curSet */
        if (Queue_empty(tsk->readyQ)) {
            Task_module->curSet &= ~tsk->mask;
        }

        if (Task_module->curTask == tsk) {
            Task_module->curQ = newQ;   /* force a Task_switch() */
                                        /* if no longer maxQ */
            /* Put current task at front of its new readyQ */
            Queue_insert(((Queue_Elem *)(newQ))->next, (Queue_Elem *)tsk);
        }
        else {
            /* place task at end of its readyQ */
            Queue_enqueue(newQ, (Queue_Elem *)tsk);
        }

        Task_module->curSet |= newMask;
    }

    tsk->priority = priority;
    tsk->mask = newMask;
    tsk->readyQ = newQ;

    if (priority < 0) {
        Task_module->curQ = NULL;   /* force a Task_switch() */
    }

    Task_module->workFlag = 1;

    Hwi_restore(hwiKey);
    Task_restore(tskKey);

    return oldPri;
}
예제 #30
0
/*
 *  ======== insert ========
 */
void Queue_insert(Queue_Elem *qelem, Queue_Elem *elem)
{
    Queue_enqueue((Queue_Object *)qelem, elem);
}