/*!\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 ++ ;
      }
   }
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
// 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;
	}
}
Exemplo n.º 4
0
Arquivo: list.c Projeto: irori/8cc
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;
}
Exemplo n.º 5
0
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], &current_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;
	}
}