/*!\fn int list_push_sorted( LIST *list , void *ptr , int (*comparator)( const void *a , const void *b ) , void (*destructor)( void *ptr ) ) *\brief Add a pointer sorted in the list , starting by the end of the list. *\param list An initilized list container. A null value will cause an error and a _log message. *\param ptr The pointer you wan to put in the list. A null value will cause an error and a _log message. *\param comparator A pointer to a function which take two void * pointers and return an int. *\param destructor Pointer to the ptr type destructor function. Leave to NULL if there isn't. *\return TRUE or FALSE. Check error messages in DEBUG mode. */ int list_push_sorted( LIST *list , void *ptr , int (*comparator)( const void *a , const void *b ) , void (*destructor)( void *ptr ) ) { LIST_NODE *nodeptr = NULL ; n_assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return FALSE ); n_assert( ptr , n_log( LOG_ERR , "invalid ptr: NULL" ); return FALSE ); if( list -> nb_max_items > 0 && ( list -> nb_items >= list -> nb_max_items ) ) { n_log( LOG_ERR , "list is full" ); return FALSE ; } if( list -> end ) { nodeptr = list -> end ; while( nodeptr && ( comparator( ptr , nodeptr -> ptr ) < 0 ) ) nodeptr = nodeptr -> prev ; if( !nodeptr ) { /* It's the lower ranked element in the sort */ list_unshift( list , ptr , destructor ); } else { /* we have a match inside the list. let's insert the datas */ LIST_NODE *node_next = nodeptr -> next ; LIST_NODE *newnode = new_list_node( ptr , destructor ); n_assert( newnode , n_log( LOG_ERR , "Couldn't allocate new node" ); return FALSE ); if( node_next ) { link_node( newnode , node_next ); } else list -> end = newnode ; link_node( nodeptr , newnode ); list -> nb_items ++ ; } }
void ind_core_expiration_add(ft_entry_t *entry) { int reason; indigo_time_t expiration_time = calc_expiration_time(entry, &reason); list_links_t *cur; /* Iterate over list in reverse order */ for (cur = expiration_queue.links.prev; cur != &expiration_queue.links; cur = cur->prev) { ft_entry_t *other = FT_ENTRY_CONTAINER(cur, expiration); if (calc_expiration_time(other, &reason) <= expiration_time) { /* 'other' expires before us. Insert after it. */ list_insert_after(cur, &entry->expiration_links); return; } } /* Lowest expiration time. Insert at front of list. */ list_unshift(&expiration_queue, &entry->expiration_links); }
// get the next element without actually removing it from the queeue. int peekQueue(simplequeue_t *msgqueue, void **data, int *size) { simplewrapper_t *swrap; pthread_mutex_lock(&(msgqueue->qlock)); if (msgqueue->cursize <= 0) { *size = 0; *data = NULL; pthread_mutex_unlock(&(msgqueue->qlock)); return EXIT_FAILURE; } else { swrap = list_shift(msgqueue->queue); *size = swrap->size; *data = &(swrap->data); list_unshift(msgqueue->queue, swrap); pthread_mutex_unlock(&(msgqueue->qlock)); return EXIT_SUCCESS; } }
List *list_reverse(List *list) { List *r = make_list(); for (Iter *i = list_iter(list); !iter_end(i);) list_unshift(r, iter_next(i)); return r; }
void syscall_handler(){ switch (current_tcb->stack->r7) { case 0x1: /* fork */ if (task_count == TASK_LIMIT) { /* Cannot create a new task, return error */ current_tcb->stack->r0 = -1; } else { /* Compute how much of the stack is used */ size_t used = stacks[current_task] + STACK_SIZE - (unsigned int*)current_tcb->stack; /* New stack is END - used */ tasks[task_count].stack = (void*)(stacks[task_count] + STACK_SIZE - used); /* Copy only the used part of the stack */ memcpy(tasks[task_count].stack, current_tcb->stack, used * sizeof(unsigned int)); /* Set PID */ tasks[task_count].pid = task_count; /* Set priority, inherited from forked task */ tasks[task_count].priority = current_tcb->priority; /* Set return values in each process */ current_tcb->stack->r0 = task_count; tasks[task_count].stack->r0 = 0; list_init(&tasks[task_count].list); list_push(&ready_list[tasks[task_count].priority], &tasks[task_count].list); /* There is now one more task */ task_count++; } break; case 0x2: /* getpid */ current_tcb->stack->r0 = current_task; break; case 0x3: /* write */ { /* Check fd is valid */ int fd = current_tcb->stack->r0; if (fd < FILE_LIMIT && files[fd]) { /* Prepare file request, store reference in r0 */ requests[current_task].task = current_tcb; requests[current_task].buf = (void*)current_tcb->stack->r1; requests[current_task].size = current_tcb->stack->r2; current_tcb->stack->r0 = (int)&requests[current_task]; /* Write */ file_write(files[fd], &requests[current_task], &event_monitor); } else { current_tcb->stack->r0 = -1; } } break; case 0x4: /* read */ { /* Check fd is valid */ int fd = current_tcb->stack->r0; if (fd < FILE_LIMIT && files[fd]) { /* Prepare file request, store reference in r0 */ requests[current_task].task = current_tcb; requests[current_task].buf = (void*)current_tcb->stack->r1; requests[current_task].size = current_tcb->stack->r2; current_tcb->stack->r0 = (int)&requests[current_task]; /* Read */ file_read(files[fd], &requests[current_task], &event_monitor); } else { current_tcb->stack->r0 = -1; } } break; case 0x5: /* interrupt_wait */ /* Enable interrupt */ NVIC_EnableIRQ(current_tcb->stack->r0); /* Block task waiting for interrupt to happen */ event_monitor_block(&event_monitor, INTR_EVENT(current_tcb->stack->r0), current_tcb); current_tcb->status = TASK_WAIT_INTR; break; case 0x6: /* getpriority */ { int who = current_tcb->stack->r0; if (who > 0 && who < (int)task_count) current_tcb->stack->r0 = tasks[who].priority; else if (who == 0) current_tcb->stack->r0 = current_tcb->priority; else current_tcb->stack->r0 = -1; } break; case 0x7: /* setpriority */ { int who = current_tcb->stack->r0; int value = current_tcb->stack->r1; value = (value < 0) ? 0 : ((value > PRIORITY_LIMIT) ? PRIORITY_LIMIT : value); if (who > 0 && who < (int)task_count) { tasks[who].priority = value; if (tasks[who].status == TASK_READY) list_push(&ready_list[value], &tasks[who].list); } else if (who == 0) { current_tcb->priority = value; list_unshift(&ready_list[value], ¤t_tcb->list); } else { current_tcb->stack->r0 = -1; break; } current_tcb->stack->r0 = 0; } break; case 0x8: /* mknod */ current_tcb->stack->r0 = file_mknod(current_tcb->stack->r0, current_tcb->pid, files, current_tcb->stack->r2, &memory_pool, &event_monitor); break; case 0x9: /* sleep */ if (current_tcb->stack->r0 != 0) { current_tcb->stack->r0 += tick_count; event_monitor_block(&event_monitor, TIME_EVENT, current_tcb); current_tcb->status = TASK_WAIT_TIME; } break; case 0xa: /* lseek */ { /* Check fd is valid */ int fd = current_tcb->stack->r0; if (fd < FILE_LIMIT && files[fd]) { /* Prepare file request, store reference in r0 */ requests[current_task].task = current_tcb; requests[current_task].buf = NULL; requests[current_task].size = current_tcb->stack->r1; requests[current_task].whence = current_tcb->stack->r2; current_tcb->stack->r0 = (int)&requests[current_task]; /* Read */ file_lseek(files[fd], &requests[current_task], &event_monitor); } else { current_tcb->stack->r0 = -1; } } break; case 0xb: /* task_block */ { event_monitor_block(&event_monitor, TASK_EVENT(current_tcb->stack->r0), current_tcb); current_tcb->status = TASK_WAIT_TASK; } break; case 0xc: /* mutex_lock */ { unsigned int mutex_addr = current_tcb->stack->r0; /* search if mutex exist */ for(int i = 0; i < MUTEX_LIMIT; i++) { if(__mutex.addr[i] == mutex_addr) { event_monitor_block(&event_monitor, MUTEX_EVENT(i), current_tcb); current_tcb->status = TASK_WAIT_MUTEX; current_tcb->stack->r0 = 0; return; } } int empty_mutex = 0; for(; empty_mutex < MUTEX_LIMIT; empty_mutex++) { if(list_empty(&event_monitor.events[MUTEX_EVENT(empty_mutex)].list)) { break; } } event_monitor_block(&event_monitor, MUTEX_EVENT(empty_mutex), current_tcb); current_tcb->status = TASK_WAIT_MUTEX; __mutex.addr[empty_mutex] = mutex_addr; __mutex.count++; current_tcb->stack->r0 = 0; } break; case 0xd: /* mutex_unlock */ { unsigned int mutex_addr = current_tcb->stack->r0; /* search if mutex exist */ for(int i = 0; i < MUTEX_LIMIT; i++) { if(__mutex.addr[i] == mutex_addr) { event_monitor_release(&event_monitor, MUTEX_EVENT(i)); current_tcb->stack->r0 = 0; __mutex.count--; return; } } current_tcb->stack->r0 = -1; } break; default: break; } }