예제 #1
0
BOOL UtMsgSend (HANDLE Dest, PVOID Data, DWORD Size){
	PMessage m;PBUFMSG bm;DWORD xx;
	/*PUTHREAD*/ RunningThread = (PUTHREAD)Dest;
	
	if(RunningThread->isWaiting){
		m = (PMessage)malloc(sizeof(Message));
		m->Buffer = Data;
		m->SizeBuffer = (PDWORD)Size;
		InsertTailList(&RunningThread->MessageQueue , &m->Link);
		InterlockedIncrement(&RunningThread->nMessages);
		RunningThread->isWaiting = 0;
		EventSet(&RunningThread->ev);
	}
	else{
		bm = (PBUFMSG)malloc(sizeof(BUFMSG));
		bm->Buffer = Data;
		bm->nSize = (PDWORD)Size;
		bm->Thread = (PHANDLE)Dest;
		InsertTailList(&QMSG , &bm->Link);
		InterlockedIncrement(&nMsg);
		if(RunningThread->isWaiting)
			EventSet(&RunningThread->ev);
	}		
	
	return TRUE;
}
예제 #2
0
int sock_server_init_epoll(int &listenfd , uint16_t server_port)
{
	listenfd = sock_server_init(listenfd, server_port);
	EventSet(&g_Events[MAX_EVENTS], listenfd, AcceptConn, &g_Events[MAX_EVENTS]);
	EventAdd(listenfd, EPOLLIN|EPOLLET, &g_Events[MAX_EVENTS]);
	return listenfd;
}
예제 #3
0
int AcceptConn(int fd, int evetns, void *arg)
{
	struct sockaddr_in sin;
	socklen_t len = sizeof(struct sockaddr_in);	
	int clientfd, index;
	if((clientfd = accept( fd, (struct sockaddr * )&sin, &len)) == -1 )
	{
		perror("accept");
		return -1;
	}
	do{
		for(index = 0; index < MAX_EVENTS; index++)
		{
			if(g_Events[index].status == 0)//not in list
			{
				break;
			}
			if(index == MAX_EVENTS)
			{
				perror("achieve MAX_EVENTS");
				break;
			}
			if(fcntl(clientfd, F_SETFL, O_NONBLOCK) < 0)
				break;

			EventSet(&g_Events[index] , clientfd, RecvData, &g_Events[index]);
			EventAdd(g_epollfd, EPOLLIN|EPOLLET, &g_Events[index]);
			printf("new connection[%s:%d] at [time:%d]\n", inet_ntoa(sin.sin_addr),
				ntohs(sin.sin_port),(int) g_Events[index].last_active);

		}//for
	}while(0);
}
예제 #4
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SchedStop
 *
 *  DESCRIPTION
 *      Stop the scheduler in order to make the Sched() function return.
 *      This is usually called from within a scheduler task like a demo-program
 *
 *  RETURNS
 *        void
 *
 *----------------------------------------------------------------------------*/
void SchedStop(void)
{
    GENINFO(("SchedStop() called\n"));
 //   _FUNC_ENTER();
    /* Set flag to interrupt the Sched loop and wake it if it's
     * sleeping */
    EventSet(&instance->eventHandle, STOP_REQ_EVENT);
}
예제 #5
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SchedBgintSet
 *
 *  DESCRIPTION
 *      Set background interrupt.
 *
 *  RETURNS
 *      void.
 *
 *----------------------------------------------------------------------------*/
void SchedBgintSet(SchedBgint irq)
{
    if (irq < BGINT_COUNT) {
        BgIntType *bgint;

        bgint = &instance->bgint[irq];

        EventSet(bgint->eventHandle, bgint->eventBit);
    }
    else {
        /* Invalid bgint */
    //    Panic(_TECH_FW, _PANIC_FW_UNEXPECTED_VALUE, "Invalid SchedBgint");
    }
}
예제 #6
0
int SendData(int fd, int events, void *arg)
{
	struct myevent_s *ev = (struct myevent_s *)arg;
	int writeback = p_write_to_p(fd, "Hi this is server");
	ev->len = 0;
	EventDel(g_epollfd, ev);
	if(writeback > 0)
	{
		EventSet(ev, fd, RecvData, ev);
		EventAdd(g_epollfd, EPOLLIN|EPOLLET, ev);
	}
	else
	{
		close(ev->fd);
		printf("send error %s , fd %d\n", strerror(errno), fd );
	}
}
예제 #7
0
NvResult CNvThreadingLinux::EventCreate(Handle *puEventHandle, bool bManual, bool bSet)
{
    *puEventHandle = NV_HANDLE_INVALID;

    CConditionData *pCond = new CConditionData;

    if (!pCond)
    {
        return RESULT_OUT_OF_HANDLES;
    }

    pCond->manual = bManual;

    if (pthread_mutex_init(&pCond->mutex, NULL))
    {
        delete pCond;
        return RESULT_OUT_OF_HANDLES;
    }

    if (pthread_cond_init(&pCond->condition, NULL))
    {
        pthread_mutex_destroy(&pCond->mutex);
        delete pCond;
        return RESULT_OUT_OF_HANDLES;
    }

    *puEventHandle = (Handle)pCond;

    if (bSet)
    {
        EventSet(*puEventHandle);
    }
    else
    {
        EventReset(*puEventHandle);
    }

    return RESULT_OK;
}
예제 #8
0
int RecvData(int fd, int events, void *arg)
{
        struct myevent_s *ev = (struct myevent_s *)arg;
        int readback = p_read_from_p(fd);
        EventDel(g_epollfd, ev);
	if(readback > 0 )
	{
		ev->len = readback;
		EventSet(ev, fd, SendData, ev);
		EventAdd(g_epollfd, EPOLLOUT|EPOLLET, ev);
	}
	else if(readback == 0)
	{
		close(ev->fd);
		printf("close fd %d gracefully\n", fd);
	}
	else
	{
		close(ev->fd);
		printf("recv error %s  fd %d \n", strerror(errno), fd);
	}
	return readback;

}
예제 #9
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      Sched
 *
 *  DESCRIPTION
 *      Starts the scheduler. The function will not return until
 *      SchedStop() has been called.
 *
 *      The data parameter is the scheduler context returned by the
 *      SchedInit() function.
 *
 *  RETURNS
 *        void
 *
 *----------------------------------------------------------------------------*/
void Sched(void *data)
{
    uint8 i;
    uint32 eventBits;
    Result result;
    uint16 readThreadIdVector;
    int8 name[8] = "sched-x";
    SchedulerInstanceType *inst = (SchedulerInstanceType *) data;

    /* Create scheduler threads */
    for (i = 0; i < _SCHED_MAX_SEGMENTS; i++) {
        if (inst->thread[i].inUse) {
            name[6] = '0' + i;

            if (ThreadCreate(SchedLoop, &inst->thread[i], inst->thread[i].stackSize, inst->thread[i].priority, name, &(inst->thread[i].thread_handle))
                != _RESULT_SUCCESS) {
            //    Panic(_TECH_FW, _PANIC_FW_UNEXPECTED_VALUE, "Thread creation failed");
            }
        }
    }

    /* Start scheduler threads */
    for (i = 0; i < _SCHED_MAX_SEGMENTS; i++) {
        if (inst->thread[i].inUse) {
            EventSet(&inst->thread[i].eventHandle, START_EVENT);
        }
    }

    /* The following handles scheduler shutdown and task deinit.
     * The shutdown sequence first signals all threads to stop
     * their scheduler loop. Then it signals all threads to run
     * their task deinit functions.
     *
     * Shutdown is successfull if all threads respond to stop and deinit
     * requests. Missing responses will cause the shutdown sequence to
     * be aborted and the incident will be logged. The Sched() function
     * will then return immediately. No panics will be generated.
     *
     * If shutdown is disabled the Sched() function will block forever.
     */

    /*
     * Block until told to exit from SchedStop(). Or block forever if
     * shutdown is disabled.
     */
    result = EventWait(&inst->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);

    if ((result != _RESULT_SUCCESS) || (eventBits != STOP_REQ_EVENT)) {
        GENERROR(("Failure in wait for task stop request"));
        return;
    }

    /* Signal all threads to stop their scheduler loop */
    for (i = 0; i < _SCHED_MAX_SEGMENTS; i ++) {
        if (inst->thread[i].inUse) {
            EventSet(&inst->thread[i].eventHandle, STOP_REQ_EVENT);
        }
    }

    /* Block until all threads are stopped. */
    eventBits = 0;
    readThreadIdVector = 0;
    while (readThreadIdVector != instance->threadIdVector) {
        result = EventWait(&inst->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);
        if ((result == _RESULT_SUCCESS) && (STOP_CFM_EVENT & eventBits)) {
            readThreadIdVector |= THREAD_ID_MASK & eventBits;
        }
        else if (result != _RESULT_SUCCESS) {
            GENERROR(("Failure in wait for thread stop confirm"));
            return;
        }
    }

    /* signal all threads to run their task deinit */
    for (i = 0; i < _SCHED_MAX_SEGMENTS; i ++) {
        if (inst->thread[i].inUse) {
            EventSet(&inst->thread[i].eventHandle, DEINIT_REQ_EVENT);
        }
    }

    /* block until all threads have completed task deinit */
    eventBits = 0;
    readThreadIdVector = 0;
    while (readThreadIdVector != instance->threadIdVector) {
        result = EventWait(&inst->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);
        if ((result == _RESULT_SUCCESS) && (DEINIT_CFM_EVENT & eventBits)) {
            readThreadIdVector |= THREAD_ID_MASK & eventBits;
        }
        else if (result != _RESULT_SUCCESS) {
            GENERROR(("Failure in wait for thread deinit confirm"));
            return;
        }
    }
}
예제 #10
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SchedLoop
 *
 *  DESCRIPTION
 *      The main function of the background task scheduler. This
 *      invokes tasks as messages become available for them and
 *      delivers timed event calls.
 *
 *
 *  RETURNS
 *        void
 *
 *----------------------------------------------------------------------------*/
void SchedLoop(void *data)
{
    ThreadInstanceType *thread;
    uint32 eventBits, timeout;
    uint32 eventBitsOther;
    Time now;
    TimerType *timer;
    uint16 i;
    Result result;

    thread = (ThreadInstanceType *) data;

    result = EventWait(&thread->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);
    if (result != _RESULT_SUCCESS) {
    //    Panic(_TECH_FW, _PANIC_FW_UNEXPECTED_VALUE, "Event wait failed");
    }
    eventBitsOther = (eventBits & ~START_EVENT);
    if (eventBitsOther) {
        /* If thread is signalled from another thread, by a message put,
         * then pass this signal to our self. */
        EventSet(&thread->eventHandle, eventBitsOther);
    }

    /* make sure the Sched loop continues until interrupted */
    thread->schedRunning = TRUE;

    /* Tasks' initialisation functions. */
    for (i = 0; i < thread->numberOfTasks; i ++) {
        thread->currentTask = (Task) (i | (thread->id << _SCHED_QUEUE_SEGMENT_SHIFT));

        if (thread->tasks[i].initFunction) {
            thread->tasks[i].initFunction(&(thread->tasks[i].instanceDataPointer));
        }
        thread->currentTask = _SCHED_TASK_ID;
    }

    i = 0;
    while (thread->schedRunning) {
        if (thread->pendingMessages > 0) {
            /* Consider each task in turn. */
            while (1) {
                TaskDefinitionType *task;

                if (i >= thread->numberOfTasks) {
                    i = 0;
                }

                task = &thread->tasks[i];
                if (task->messageQueueFirst) {
                    thread->currentTask = (int) (i | (thread->id << _SCHED_QUEUE_SEGMENT_SHIFT));

                    task->handlerFunction(&(task->instanceDataPointer));

                    thread->currentTask = _SCHED_TASK_ID;
                    i++;
                    break;
                }
                else {
                    i++;
                }
            }
        }

        /* if no internal messages wait for external event or a timer to to expire */
        if (thread->pendingMessages == 0) {
            /* Currently there is no messages on any of the Scheduler
               task queues. Wait for a timer or an external event to occur */
            if (thread->timerList != NULL) {
                now = TimeGet(NULL);
                if (thread->timerList->wrapCount > thread->currentWrapCount) {
                    timeout = (_SCHED_TIME_MAX - now + thread->timerList->when);
                    /* Avoid rounding to zero in division below. */
                    timeout += 999;
                }
                else {
                    if (now < thread->timerList->when) {
                        timeout = TimeSub(thread->timerList->when, now);
                        /* Avoid rounding to zero in division below. */
                        timeout += 999;
                    }
                    else {
                        timeout = 0;
                    }
                }
                timeout /= 1000;
                if (timeout >= _EVENT_WAIT_INFINITE) {
                    timeout = _EVENT_WAIT_INFINITE - 1;
                }
            }
            else {
                timeout = _EVENT_WAIT_INFINITE;
            }
        }
        else {
            timeout = 0;
        }
        if (EventWait(&thread->eventHandle, (uint16) timeout, &eventBits) == _RESULT_SUCCESS) {
            /* background interrupt */
            SchedBgint vector;

            vector = (SchedBgint) (eventBits & BG_INT_MASK);

            /* Are any background interrupts set? */
            if (vector) {
                uint32 j;

                j = 0;

                do {
                    BgIntType *bgint;

                    bgint = &instance->bgint[j];

                    /* Check if this bgint is set */
                    if (vector & bgint->eventBit) {
                        /* Clear the bit so the bgint is accounted for. */
                        vector &= ~bgint->eventBit;

                        thread->currentTask = bgint->qid;

                        bgint->handler(bgint->arg);

                        thread->currentTask = _SCHED_TASK_ID;
                    }

                    j++;
                } while (vector);
            }

            /* a message arriving from outside */
            if (EXT_MSG_EVENT & eventBits) {
                SchedTaskId qi;
                MessageQueueEntryType *message;

                MutexLock(&thread->qMutex);

                while (thread->extMsgQueueFirst != NULL) {
                    /* remove from ext queue */
                    message = thread->extMsgQueueFirst;
                    thread->extMsgQueueFirst = message->next;
                    message->next = NULL;

                    qi = message->receiver;

                    /* ...store the on the end of the task's message chain. */
                    if (thread->tasks[qi].messageQueueLast == NULL) {
                        thread->tasks[qi].messageQueueFirst = message;
                        thread->tasks[qi].messageQueueLast = message;
                    }
                    else {
                        thread->tasks[qi].messageQueueLast->next = message;
                        thread->tasks[qi].messageQueueLast = message;
                    }
                    thread->pendingMessages++;
                }

                /* At this point the external queue is empty. */
                thread->extMsgQueueLast = NULL;

                MutexUnlock(&thread->qMutex);
            }
            /* a sched stop req */
            if (STOP_REQ_EVENT & eventBits) {
                /* return stop cfm and break out of scheduler loop */
                thread->schedRunning = FALSE;
                EventSet(&instance->eventHandle, STOP_CFM_EVENT | (0x0001 << (uint32) thread->id));
                break;
            }
        }

        while (thread->timerList) {
            /* Now, back to timed events. */
            now = TimeGet(NULL);
            /* Handle timer wrap */
            adjust_wrap_count(thread, now);

            if (thread->timerList->wrapCount > thread->currentWrapCount) {
                /* The earliest deadline is more than 1 wrapCount in the future. */
                break;
            }
            else {
                if ((thread->timerList->when > now) &&
                    (thread->timerList->wrapCount == thread->currentWrapCount)) {
                    break;
                }
                else {
                    /* Run the timed event function. */
                    timer = thread->timerList;
                    timer->active = FALSE;

                    thread->timerList = timer->next;
                    if (thread->timerList != NULL) {
                        thread->timerList->prev = NULL;
                    }

                    thread->currentTask = timer->queue;

                    timer->eventFunction(timer->id, timer->fniarg, timer->fnvarg);

                    thread->currentTask = _SCHED_TASK_ID;

                    timerFree(thread, timer);
                }
            }
        }
    } /*  while (thread->schedRunning) */

    /* wait for deinit req event */
    while (1) {
        eventBits = 0;
        result = EventWait(&thread->eventHandle, _EVENT_WAIT_INFINITE, &eventBits);
        if ((result == _RESULT_SUCCESS) && (DEINIT_REQ_EVENT & eventBits)) {
            SchedTaskId qi;
            MessageQueueEntryType *message;

            /*
             * Pull any messages off the external queue and
             * put them on the relevant task queue. These may
             * be put here after we stopped because the sender
             * had not received its stop event yet.
             */
            while (thread->extMsgQueueFirst != NULL) {
                /* remove from ext queue */
                message = thread->extMsgQueueFirst;
                thread->extMsgQueueFirst = message->next;
                message->next = NULL;

                qi = message->receiver;

                /* ...store the on the end of the task's message chain. */
                if (thread->tasks[qi].messageQueueLast == NULL) {
                    thread->tasks[qi].messageQueueFirst = message;
                    thread->tasks[qi].messageQueueLast = message;
                }
                else {
                    thread->tasks[qi].messageQueueLast->next = message;
                    thread->tasks[qi].messageQueueLast = message;
                }
                thread->pendingMessages++;
            }

            /* deinit all tasks in this scheduler thread and
             * return deinit cfm */
            SchedInstanceTaskDeinit(thread);
            EventSet(&instance->eventHandle, DEINIT_CFM_EVENT | (0x0001 << (uint32) thread->id));
            return;
        }
        else if (result != _RESULT_SUCCESS) {
            GENERROR(("Failure in wait for thread deinit req"));
            return;
        }
    }
}
예제 #11
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      do_put_message
 *
 *  DESCRIPTION
 *      Does the actual work of SchedMessagePut().
 *
 *  RETURNS
 *      -
 *
 *----------------------------------------------------------------------------*/
static void do_put_message(Task dst,
    uint16 mi,
    void *mv)
{
    ThreadInstanceType *src_thread;
    Task currentTask;
    uint16 qi;
    uint8 src_index, dest_index;

    src_index = GetThreadIndex();
    if (src_index < _SCHED_MAX_SEGMENTS) {
        src_thread = &instance->thread[src_index];
        currentTask = src_thread->currentTask;
    }
    else {
        src_thread = NULL;
        currentTask = _SCHED_TASK_ID;
    }

    /* Get segment and task index */
    dest_index = QUEUE_EXTRACT_SEGMENT(dst);
    qi = QUEUE_EXTRACT_INDEX(dst);

    if (dest_index < _SCHED_MAX_SEGMENTS) {
        /* this message is destined for another sched task */
        MessageQueueEntryType *message;
        ThreadInstanceType *dest_thread = &instance->thread[dest_index];

        if (!dest_thread->inUse || (qi >= dest_thread->numberOfTasks)) {
            /* Task index is out-of-bounds */
            GENERROR(("dest_thread->numberOfTasks=%d,qi=%d\n",
            dest_thread->numberOfTasks, qi));
            GENERROR(("Invalid receiver task"));
            return;
        //    Panic(_TECH_FW, _PANIC_FW_UNKNOWN_TASK, "Invalid receiver task");
        }

        /* Package the message for queue storage. */
        if (currentTask != _SCHED_TASK_ID) {
            message = messageAlloc(src_thread);
        }
        else {
            message = pnew(MessageQueueEntryType);
        }
        message->next = NULL;
        message->event = mi;
        message->sender = currentTask;
        message->message = mv;

        if (src_index == dest_index) { /* message to the calling thread */
            TaskDefinitionType *task;

            task = &dest_thread->tasks[qi];

            /* Store the message on the end of the task's message chain. */
            if (task->messageQueueLast == NULL) {
                task->messageQueueFirst = message;
                task->messageQueueLast = message;
            }
            else {
                task->messageQueueLast->next = message;
                task->messageQueueLast = message;
            }
            dest_thread->pendingMessages++;
        }
        else { /* message to another thread than the calling */
            message->receiver = qi;
            MutexLock(&dest_thread->qMutex);

            if (dest_thread->extMsgQueueLast == NULL) {
                dest_thread->extMsgQueueFirst = message;
                dest_thread->extMsgQueueLast = message;
            }
            else {
                dest_thread->extMsgQueueLast->next = message;
                dest_thread->extMsgQueueLast = message;
            }

            MutexUnlock(&dest_thread->qMutex);

            EventSet(&dest_thread->eventHandle, EXT_MSG_EVENT);
        }
    }
    else {
        /* this message is destined for an external receiver */
        if (externalSend != NULL) {
            /* Message flagged for remote scheduler/thread thingy */            
            externalSend(dst, mi, mv);
        }
        else {
            /* Not handler for this segment! */
        //    Panic(_TECH_FW, _PANIC_FW_UNKNOWN_TASK,
        //        "Invalid destination queue or no external send function registered");
        }
    }
}