static inline int dequeue(struct queue *queue, int *data) { CHECK_QUEUE_POINTER(queue); if (1 == is_queue_empty(queue)) { fprintf(stderr, "queue is empty\n"); return 1; } if (NULL != data) *data = queue->data[queue->front]; queue->front = (queue->front +1) % MAX_QUEUE_SIZE; queue->flag = 0; return 0; }
/** * * @param dque * @param data_ptr * * @return TN_RETVAL */ TN_RETVAL tnnc_queue_isend_polling (TN_DQUE_S *dque, void *data_ptr) { TN_UWORD tn_save_status_reg TN_UNUSED; TN_RETVAL rc; CDLL_QUEUE_S *que; TN_TCB_S *task; /* Not check parameter error if (dque == TN_NULL) return TERR_WRONG_PARAM; */ if (dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; if (tn_is_non_sys_int_context()) { return TERR_WCONTEXT; } tn_idisable_interrupt(); if (!is_queue_empty(&(dque->wait_receive_list))) { que = queue_remove_head(&(dque->wait_receive_list)); task = get_task_by_tsk_queue(que); task->data_elem = data_ptr; if (task_wait_complete(task, TN_FALSE)) { tn_context_switch_request = TN_TRUE; tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { rc = dque_fifo_write(dque,data_ptr); if (rc != TERR_NO_ERR) { rc = TERR_TIMEOUT; } } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- // Release Semaphore Resource //---------------------------------------------------------------------------- int tn_sem_signal(TN_SEM * sem) { TN_INTSAVE_DATA int rc; //-- return code CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(sem == NULL) return TERR_WRONG_PARAM; if(sem->max_count == 0) return TERR_WRONG_PARAM; if(sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT tn_disable_interrupt(); if(!(is_queue_empty(&(sem->wait_queue)))) { //--- delete from the sem wait queue que = queue_remove_head(&(sem->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { tn_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { if(sem->count < sem->max_count) { sem->count++; rc = TERR_NO_ERR; } else rc = TERR_OVERFLOW; } tn_enable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_iwait(TN_EVENT * evf, unsigned int wait_pattern, int wait_mode, unsigned int * p_flags_pattern) { TN_INTSAVE_DATA_INT int rc; int fCond; #if TN_CHECK_PARAM if(evf == NULL || wait_pattern == 0 || p_flags_pattern == NULL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); //-- If event attr is TN_EVENT_ATTR_SINGLE and another task already //-- in event wait queue - return ERROR without checking release condition if((evf->attr & TN_EVENT_ATTR_SINGLE) && !is_queue_empty(&(evf->wait_queue))) { rc = TERR_ILUSE; } else { //-- Check release condition if(wait_mode & TN_EVENT_WCOND_OR) //-- any setted bit is enough for release condition fCond = ((evf->pattern & wait_pattern) != 0); else //-- TN_EVENT_WCOND_AND is default mode fCond = ((evf->pattern & wait_pattern) == wait_pattern); if(fCond) { *p_flags_pattern = evf->pattern; if(evf->attr & TN_EVENT_ATTR_CLR) evf->pattern = 0; rc = TERR_NO_ERR; } else rc = TERR_TIMEOUT; } tn_ienable_interrupt(); return rc; }
void keyboard_read(u32* key) { u8 scan_code; u32 col; BOOL b_shift; if (!is_queue_empty(&kb_queue)) { io_cli(); de_queue(&kb_queue, &scan_code); io_sti(); /* 首先处理E0 开头的情况,将b_leading_e0置位,然后直接返回 */ if (scan_code == 0xe0) { b_leading_e0 = TRUE; return; } /* 是键被抬起,暂时将键值设为0 */ if (scan_code & 0x80) { if (*key == K_SHIFT_L) b_shift_l = 0; if (*key == K_SHIFT_R) b_shift_r = 0; *key = 0; return; } b_shift = b_shift_l || b_shift_r; col = b_shift ? 1 : 0; if (b_leading_e0) { col = 2; b_leading_e0 = FALSE; } *key = keymap[scan_code & 0x7f][col]; if (*key == K_SHIFT_L) b_shift_l = 1; if (*key == K_SHIFT_R) b_shift_r = 1; b_shift = b_shift_l || b_shift_r; } }
static void en_queue(Queue* q,Customer* c) { c->time_stamp = now_time; if(is_queue_empty(q)) { q->tail = q->head = c; q->tail->next = NULL; q->head->prev = NULL; }else{ c->prev = q->tail; q->tail->next = c; q->tail = c; q->tail->next = NULL; } }
void *consumer(void *arg) { pthread_mutex_lock(&mutex); while(is_queue_empty(Q)){ pthread_cond_wait(&full, &mutex); } int data; dequeue(&Q, &data); Q.size --; printf("Consumer a produce %d.\n", data); pthread_cond_signal(&empty); pthread_mutex_unlock(&mutex); }
int enqueue(Queue* queue, Node* node) { if (NULL == queue || NULL == node) return RTX_ERR; node->next = NULL; if (is_queue_empty(queue)) { queue->first = node; queue->last = node; } else { queue->last->next = node; queue->last = queue->last->next; } return RTX_OK; }
simple_thread_task* simple_thread_pool::acquire_task() { insync(cs_); t_task_list::iterator iter = task_list_.first(); if (iter.is_valid()) { task_list_.remove(iter); } if (is_queue_empty()) ResetEvent(have_task_); return iter.is_valid() ? *iter : NULL; }
//---------------------------------------------------------------------------- int tn_queue_isend_polling(TN_DQUE * dque, void * data_ptr) { TN_INTSAVE_DATA_INT int rc; CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(dque == NULL) return TERR_WRONG_PARAM; if(dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); //-- there are task(s) in the data queue's wait_receive list if(!is_queue_empty(&(dque->wait_receive_list))) { que = queue_remove_head(&(dque->wait_receive_list)); task = get_task_by_tsk_queue(que); task->data_elem = data_ptr; if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else //-- the data queue's wait_receive list is empty { rc = dque_fifo_write(dque,data_ptr); if(rc != TERR_NO_ERR) //-- No free entries in data queue rc = TERR_TIMEOUT; //-- Just convert errorcode } tn_ienable_interrupt(); return rc; }
void ssd_perform_refresh(ssd_t *currdisk, double now) { int size = ll_get_size(currdisk->refresh_queue); int i=0,blocks_to_refresh=0; double next_refresh_time = currdisk->params.refresh_interval + currdisk->params.refresh_service_time * currdisk->params.nelements * currdisk->params.blocks_per_element/1000; //This value is an upper bound on the refresh time. listnode **clean_blocks_issue_list = (listnode**)malloc(currdisk->params.nelements * sizeof(listnode*)); for(i=0;i<currdisk->params.nelements;i++) ll_create(&clean_blocks_issue_list[i]); i=0; while(i<size) { listnode* currnode = ll_get_nth_node(currdisk->refresh_queue,i); block_metadata* currblock = (block_metadata*)currnode->data; ssd_page_metadata* least_retention_page = currblock->least_retention_page; //assert(now - least_retention_page->time_of_last_stress >0); //least_retention_page->retention_period -= (now - least_retention_page->time_of_last_stress); //account for time spent idling. if(ssd_block_dead(currblock,currdisk)) //Too late, block is dead. Handle it accordingly continue; //check if currblock needs refresh *now* if(current_retention_period(currblock) < next_refresh_time || ssd_virtual_retention_expired(currblock,currdisk)) { refresh_queue_free_node(currdisk->refresh_queue,currblock); blocks_to_refresh++;size--; ll_insert_at_tail(clean_blocks_issue_list[currblock->elem_num],currblock); } i++; } if(blocks_to_refresh!=0) { fprintf(stderr, "# of blocks to refresh :%d\n",blocks_to_refresh); } for(i=0;i<currdisk->params.nelements;i++) { if(is_queue_empty(clean_blocks_issue_list[i])) continue; fprintf(stderr, "About to refresh %d blocks in elem #%d\n",ll_get_size(clean_blocks_issue_list[i]),i); ssd_invoke_element_refresh_fcfs(i,clean_blocks_issue_list[i],currdisk); ll_release(clean_blocks_issue_list[i]); } }
static Customer* out_queue(Queue* q) { Customer *c = NULL; if(!is_queue_empty(q)) { c = q->head; if(q->head==q->tail) { q->head=q->tail=NULL; }else{ q->head = q->head->next; q->head->prev = NULL; } c->next = NULL; c->prev = NULL; } return c; }
/* 元素入队 */ q_node_t push_queue(Queue *q,q_item n) { q_node_t qnode; qnode = (q_node_t)malloc(sizeof(q_node_t)); if(qnode != NULL){ qnode->data = n; qnode->next = NULL; if(is_queue_empty(q) == 1){ q->front = qnode; } else{ q->rear->next = qnode; } q->rear = qnode; q->size++; } return qnode; }
/** watcher : watch the work queues, to find out if there is work to do @handle : the uv_prepare_t **/ void cspider_watcher(uv_prepare_t *handle) { cspider_t *cspider = (cspider_t*)handle->data; if (get_status_num(cspider->page_queue, PAGE_DOWNLOAD_WAIT) != 0) { /* if there is task unhandled yet, start work thread */ /* get new thread worker */ uv_work_t *req = (uv_work_t*)malloc(sizeof(uv_work_t)); PANIC(req); /* let thread worker point to the page which status is (url_add)*/ req->data = get_status_page(cspider->page_queue, PAGE_DOWNLOAD_WAIT); /* new page point to new thread worker too. */ ((cs_page*)req->data)->worker = req; /* change status (url_add) -> (url_download)*/ set_status(cspider->page_queue, (cs_page*)req->data, PAGE_DOWNLOAD_RUNNING); /* begin thread */ uv_queue_work(cspider->loop, req, cspider_download, cspider_download_done); } if (get_status_num(cspider->page_queue, PAGE_PROCESS_WAIT) != 0) { /* if there is data required to be processed */ /* get new thread worker */ uv_work_t *req = (uv_work_t*)malloc(sizeof(uv_work_t)); PANIC(req); /* let thread worker point to the page which status is (page_add) */ req->data = (cs_page*)get_status_page(cspider->page_queue, PAGE_PROCESS_WAIT); /* new page point to new thread worker too. */ ((cs_page*)req->data)->worker = req; /* change status (page_add) -> (url_process)*/ set_status(cspider->page_queue, (cs_page*)req->data, PAGE_PROCESS_RUNNING); /* begin thread */ uv_queue_work(cspider->loop, req, cspider_process, cspider_process_done); } if (is_queue_empty(cspider->page_queue) == 0) { /* if page queue is empty, then stop cspider*/ uv_prepare_stop(handle); } }
int remove(Queue* queue, Node* node) { Node* cur = NULL; Node* prev = NULL; if (NULL == queue || is_queue_empty(queue) || NULL == node) return RTX_ERR; // ERROR: queue is NULL, queue is empty, or node is NULL if (node == queue->first) { /*#ifdef DEBUG_0 printf("node == queue -> first.\n\r"); #endif*/ if (queue->first == queue->last) { queue->first = NULL; queue->last = NULL; } else { queue->first = queue->first->next; } return RTX_OK; } cur = queue->first->next; prev = queue->first; while (cur != NULL && prev != NULL) { if (node == cur) { if (cur == queue->last) { queue->last = prev; } /*#ifdef DEBUG_0 printf("node == cur\n\r"); #endif*/ prev->next = cur->next; return RTX_OK; } prev = cur; cur = cur->next; } return RTX_ERR; // ERROR: not found }
// straight to the tail void enqueue(task_t *t, runqueue_t *rq) { // de-link task from all queues dequeue_all(t); // add it to tail of rq if(is_queue_empty(rq)) { INIT_LIST_HEAD(&t->run_list); rq->head = t; } else { task_t *curTail = rq->tail; list_t *l = &curTail->run_list; // run_list is struct in task_struct l->next = &t->run_list; (&t->run_list)->prev = l; } // tail it baby rq->tail = t; }
// A utility function to delete a frame from queue void del_queue(Queue* queue) { if (is_queue_empty(queue)) return; // if this is the only node in list, then change front if (queue->front == queue->rear) queue->front = NULL; Node* temp = queue->rear; queue->rear = queue->rear->prev; if (queue->rear) queue->rear->next = NULL; free(temp); queue->count--; }
// event handler static void event_handle(Event* e) { Component* component = component_list[e->component_id]; switch(e->event_type) { case ARRIVAL: { Customer *c; double next_time = generate_customer(C2G(component),e->timestamp,&c); Event* departure_event = event_router(c,C2G(component)->D); if(departure_event) { schedule_event(departure_event); } Event *arrival_event = e;//reuse e->timestamp = next_time; schedule_event(arrival_event); }break; case DEPARTURE: { Queue* queue = C2Q(component); Customer *c = out_queue(queue); c->time_serve = e->serve_time; double next_time = simulation_serve(c,queue); Event* departure_event = event_router(c,queue->D); if(departure_event) { schedule_event(departure_event); } if(!is_queue_empty(queue)) { Event* next_departure_event = e; next_departure_event->timestamp = next_time; next_departure_event->serve_time = next_time - now_time; schedule_event(next_departure_event); }else free(e); }break; default: printf("event type error\n"); exit(-1); } }
static inline int print_queue(struct queue *queue) { CHECK_QUEUE_POINTER(queue); int i, start; if (1 == is_queue_empty(queue)) { return 0; } else { if (1 == is_queue_full(queue)) { fprintf(stdout, "queue[%d]:%d\n", queue->front, queue->data[queue->front]); start = (queue->front + 1) % MAX_QUEUE_SIZE; } else { start = queue->front; } for (i = start; i != queue->rear; i = (i + 1) % MAX_QUEUE_SIZE) { fprintf(stdout, "queue[%d]:%d\n", i, queue->data[i]); } } }
// This method is non-blocking (i.e. it can NEVER cause preemption). It is used by the // kernal processes since kernel processes should never block. void* k_receive_message_nb(int* sender_id) { MSG_BUF* env; __disable_irq(); if (is_queue_empty(&(gp_current_process->msg_queue))) { sender_id = NULL; __enable_irq(); return NULL; } env = (MSG_BUF*)dequeue(&(gp_current_process->msg_queue)); if (sender_id != NULL) { *sender_id = env->m_send_pid; } __enable_irq(); return (void*)env; }
void bfs(int size, int matrix[size][size], int visited[size], int vertex) { QUEUEPTR queue = create_queue(); queue = enqueue(queue, vertex); visited[vertex] = 1; int front, i; while(!is_queue_empty(queue)) { front = get_front(queue); printf("Vertex %d touched.", front); queue = dequeue(queue); for(i = 0; i < size; i++) { if(matrix[front][i] && !visited[i]) { visited[i] = 1; queue = enqueue(queue, i); } } } }
//---------------------------------------------------------------------------- int tn_fmem_delete(TN_FMP * fmp) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(fmp == NULL) return TERR_WRONG_PARAM; if(fmp->id_fmp != TN_ID_FSMEMORYPOOL) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT while(!is_queue_empty(&(fmp->wait_queue))) { tn_disable_interrupt(); //--- delete from sem wait queue que = queue_remove_head(&(fmp->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) tn_disable_interrupt(); fmp->id_fmp = 0; //-- Fixed-size memory pool not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_sem_delete(TN_SEM * sem) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(sem == NULL) return TERR_WRONG_PARAM; if(sem->id_sem != TN_ID_SEMAPHORE) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT while(!is_queue_empty(&(sem->wait_queue))) { tn_disable_interrupt(); //--- delete from the sem wait queue que = queue_remove_head(&(sem->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); sem->id_sem = 0; // Semaphore not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_fmem_release(TN_FMP * fmp,void * p_data) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(fmp == NULL || p_data == NULL) return TERR_WRONG_PARAM; if(fmp->id_fmp != TN_ID_FSMEMORYPOOL) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT tn_disable_interrupt(); if(!is_queue_empty(&(fmp->wait_queue))) { que = queue_remove_head(&(fmp->wait_queue)); task = get_task_by_tsk_queue(que); task->data_elem = p_data; if(task_wait_complete(task)) { tn_enable_interrupt(); tn_switch_context(); return TERR_NO_ERR; } } else fm_put(fmp,p_data); tn_enable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_event_delete(TN_EVENT * evf) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(evf == NULL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT tn_disable_interrupt(); // v.2.7 - thanks to Eugene Scopal while(!is_queue_empty(&(evf->wait_queue))) { //--- delete from sem wait queue que = queue_remove_head(&(evf->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); tn_disable_interrupt(); // v.2.7 } } evf->id_event = 0; // Event not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
//---------------------------------------------------------------------------- int tn_event_delete(TN_EVENT * evf) { TN_INTSAVE_DATA CDLL_QUEUE * que; TN_TCB * task; if(evf == NULL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; TN_CHECK_NON_INT_CONTEXT while(!is_queue_empty(&(evf->wait_queue))) { if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); //--- delete from sem wait queue que = queue_remove_head(&(evf->wait_queue)); task = get_task_by_tsk_queue(que); if(task_wait_complete(task,FALSE)) { task->task_wait_rc = TERR_DLT; tn_enable_interrupt(); tn_switch_context(); } } if(tn_chk_irq_disabled() == 0) // int enable tn_disable_interrupt(); evf->id_event = 0; // Event not exists now tn_enable_interrupt(); return TERR_NO_ERR; }
void timer_i_process() { MSG_BUF* message; //void* message_envelope; int receiver_id; /* This code is only required if delayed_send() adds a message to timer i process message queue But, we add the delayed message directly to the timeout queue */ // while (!is_queue_empty(&gp_pcbs[PID_TIMER_IPROC]->msg_queue)) { // message_envelope = (MSG_BUF *)dequeue(&gp_pcbs[PID_TIMER_IPROC]->msg_queue); // timeout_queue_enqueue(message_envelope); // } while (!is_queue_empty(&timeout_queue) && ((MSG_BUF *)((&timeout_queue)->first))->m_kdata[0] <= g_timer_count) { message = (MSG_BUF *)dequeue(&timeout_queue); receiver_id = message->m_recv_pid; if (k_send_message_helper(message->m_send_pid,receiver_id, message) == 1 && gp_pcbs[receiver_id]->m_priority < gp_current_process->m_priority) { __enable_irq(); // atomic (off) k_release_processor(); __disable_irq(); // atomic (on) } } }
int main() { queue_t *q1 = mk_queue(); printf("%d\n", get_len(q1)); printf("%d\n", is_queue_empty(q1)); enqueue(q1, mk_task(f1,(void *) 5)); enqueue(q1, mk_task(f2, (void *)7)); printf("%d\n", get_len(q1)); printf("%d\n", is_queue_empty(q1)); enqueue(q1, mk_task(f2, (void *)2)); enqueue(q1, mk_task(f1, (void *)9)); printf("%d\n", get_len(q1)); printf("%d\n", is_queue_empty(q1)); run_task(dequeue(q1)); run_task(dequeue(q1)); printf("%d\n", get_len(q1)); printf("%d\n", is_queue_empty(q1)); run_task(dequeue(q1)); run_task(dequeue(q1)); printf("%d\n", get_len(q1)); printf("%d\n", is_queue_empty(q1)); empty_queue(q1); enqueue(q1, mk_task(f2, (void *)2)); enqueue(q1, mk_task(f1, (void *)9)); printf("%d\n", get_len(q1)); printf("%d\n", is_queue_empty(q1)); destroy_queue(q1); }
//---------------------------------------------------------------------------- int tn_queue_ireceive(TN_DQUE * dque,void ** data_ptr) { TN_INTSAVE_DATA_INT int rc; CDLL_QUEUE * que; TN_TCB * task; #if TN_CHECK_PARAM if(dque == NULL || data_ptr == NULL) return TERR_WRONG_PARAM; if(dque->id_dque != TN_ID_DATAQUEUE) return TERR_NOEXS; #endif TN_CHECK_INT_CONTEXT tn_idisable_interrupt(); rc = dque_fifo_read(dque,data_ptr); if(rc == TERR_NO_ERR) //-- There was entry(s) in data queue { if(!is_queue_empty(&(dque->wait_send_list))) { que = queue_remove_head(&(dque->wait_send_list)); task = get_task_by_tsk_queue(que); dque_fifo_write(dque,task->data_elem); //-- Put to data FIFO if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } } } else //-- data FIFO is empty { if(!is_queue_empty(&(dque->wait_send_list))) { que = queue_remove_head(&(dque->wait_send_list)); task = get_task_by_tsk_queue(que); *data_ptr = task->data_elem; //-- Return to caller if(task_wait_complete(task)) { tn_ienable_interrupt(); return TERR_NO_ERR; } rc = TERR_NO_ERR; } else { rc = TERR_TIMEOUT; } } tn_ienable_interrupt(); return rc; }
//---------------------------------------------------------------------------- int tn_event_wait(TN_EVENT * evf, unsigned int wait_pattern, int wait_mode, unsigned int * p_flags_pattern, unsigned long timeout) { TN_INTSAVE_DATA int rc; int fCond; #if TN_CHECK_PARAM if(evf == NULL || wait_pattern == 0 || p_flags_pattern == NULL || timeout == 0) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; #endif TN_CHECK_NON_INT_CONTEXT tn_disable_interrupt(); //-- If event attr is TN_EVENT_ATTR_SINGLE and another task already //-- in event wait queue - return ERROR without checking release condition if((evf->attr & TN_EVENT_ATTR_SINGLE) && !is_queue_empty(&(evf->wait_queue))) { rc = TERR_ILUSE; } else { //-- Check release condition if(wait_mode & TN_EVENT_WCOND_OR) //-- any setted bit is enough for release condition fCond = ((evf->pattern & wait_pattern) != 0); else //-- TN_EVENT_WCOND_AND is default mode fCond = ((evf->pattern & wait_pattern) == wait_pattern); if(fCond) { *p_flags_pattern = evf->pattern; if(evf->attr & TN_EVENT_ATTR_CLR) evf->pattern = 0; rc = TERR_NO_ERR; } else { tn_curr_run_task->ewait_mode = wait_mode; tn_curr_run_task->ewait_pattern = wait_pattern; task_curr_to_wait_action(&(evf->wait_queue), TSK_WAIT_REASON_EVENT, timeout); tn_enable_interrupt(); tn_switch_context(); if(tn_curr_run_task->task_wait_rc == TERR_NO_ERR) *p_flags_pattern = tn_curr_run_task->ewait_pattern; return tn_curr_run_task->task_wait_rc; } } tn_enable_interrupt(); return rc; }