Ejemplo n.º 1
0
bool route_find (u32 address, ipv4_interface_type **interface,
                 bool *direct, ipc_structure_type **ethernet_structure)
{
  ipv4_interface_list_type *entry;

  mutex_wait (interface_list_mutex);
  entry = interface_list;

  while (entry != NULL)
  {
    /* Check if this address is on this interface's network. */

    if (entry->interface->up &&
        (entry->interface->ip_address & entry->interface->netmask) ==
        (address & entry->interface->netmask))
    {
      break;
    }

    entry = (ipv4_interface_list_type *) entry->next;
  }  

  if (entry == NULL)
  {
    mutex_signal (interface_list_mutex);
    return FALSE;
  }

  *interface = entry->interface;
  *ethernet_structure = entry->ethernet_structure;
  mutex_signal (interface_list_mutex);

  *direct = FALSE;
  return TRUE;
}
Ejemplo n.º 2
0
/*
 * Sender task. Argument is a priority value.
 * Randomly sends signals (text messages) to locks A, B and C.
 */
void main_sender (void *arg)
{
	int prio = (int) arg;
	unsigned char msgA [8], msgB [8], msgC [8];

	strcpy (msgA, (unsigned char*) "A-0"); msgA [2] += prio;
	strcpy (msgB, (unsigned char*) "B-0"); msgB [2] += prio;
	strcpy (msgC, (unsigned char*) "C-0"); msgC [2] += prio;
	for (;;) {
		switch (rand15() % 3) {
		case 0:
			/*debug_printf ("signal %s\n", msgA);*/
			mutex_signal (&A, msgA);
			break;
		case 1:
			/*debug_printf ("signal %s\n", msgB);*/
			mutex_signal (&B, msgB);
			break;
		case 2:
			/*debug_printf ("signal %s\n", msgC);*/
			mutex_signal (&C, msgC);
			break;
		}
		timer_delay (&timer, rand15() % 10 * 100);
	}
}
Ejemplo n.º 3
0
DECLARE_TEST(mutex, basic) {
	mutex_t* mutex;

	mutex = mutex_allocate(STRING_CONST("test"));

	EXPECT_CONSTSTRINGEQ(mutex_name(mutex), string_const(STRING_CONST("test")));
	EXPECT_TRUE(mutex_try_lock(mutex));
	EXPECT_TRUE(mutex_lock(mutex));
	EXPECT_TRUE(mutex_try_lock(mutex));
	EXPECT_TRUE(mutex_lock(mutex));

	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));

	log_set_suppress(0, ERRORLEVEL_WARNING);
	EXPECT_FALSE(mutex_unlock(mutex));
	log_set_suppress(0, ERRORLEVEL_INFO);

	mutex_signal(mutex);
	thread_yield();
	EXPECT_TRUE(mutex_try_wait(mutex, 1));
	EXPECT_TRUE(mutex_unlock(mutex));

	mutex_signal(mutex);
	thread_yield();
	EXPECT_TRUE(mutex_wait(mutex));
	EXPECT_TRUE(mutex_unlock(mutex));

	log_set_suppress(0, ERRORLEVEL_WARNING);
	EXPECT_FALSE(mutex_try_wait(mutex, 100));
	EXPECT_FALSE(mutex_unlock(mutex));
	log_set_suppress(0, ERRORLEVEL_INFO);

	mutex_signal(mutex);
	thread_yield();
	EXPECT_TRUE(mutex_try_wait(mutex, 1));
	log_set_suppress(0, ERRORLEVEL_WARNING);
	EXPECT_FALSE(mutex_try_wait(mutex, 100));
	EXPECT_TRUE(mutex_unlock(mutex));
	EXPECT_FALSE(mutex_unlock(mutex));
	log_set_suppress(0, ERRORLEVEL_INFO);

	mutex_deallocate(mutex);

	return 0;
}
Ejemplo n.º 4
0
/*
 * Poll for interrupts.
 * Must be called by user in case there is a chance to lose an interrupt.
 */
void eth_poll(eth_t *u) {
	uint32_t lock = mutex_trylock(&u->netif.lock);
	if (handle_interrupt(u))
		mutex_signal(&u->netif.lock, 0);
	if (lock)
		mutex_unlock(&u->netif.lock);
}
Ejemplo n.º 5
0
/*
 * Start transmitting a byte.
 * Assume the transmitter is stopped, and the transmit queue is not empty.
 * Return 1 when we are expecting the hardware interrupt.
 */
static bool_t
uartx_transmit_start (uartx_t *u)
{
	if (u->out_first == u->out_last)
		mutex_signal (&u->transmitter, 0);

	/* Check that transmitter buffer is busy. */
	if (! (UARTX_LSR(u->port) & MC_LSR_TXRDY)) {
		return 1;
	}

	/* Nothing to transmit or no CTS - stop transmitting. */
	if (u->out_first == u->out_last) {
		/* Disable `transmitter empty' interrupt. */
		UARTX_IER (u->port) &= ~MC_IER_ETXRDY;
		return 0;
	}

	/* Send byte. */
	UARTX_THR (u->port) = *u->out_first;

	++u->out_first;
	if (u->out_first >= u->out_buf + UART_OUTBUFSZ)
		u->out_first = u->out_buf;

	/* Enable `transmitter empty' interrupt. */
	UARTX_IER (u->port) |= MC_IER_ETXRDY;
	return 1;
}
Ejemplo n.º 6
0
void cb_purge(CircBuff_t * cb) {
	if (cb->invalid) return;
	critical_enter(&cb->mutex);

    cb->remaining_capacity = cb->buffer_size; // how many elements could be loaded
    cb->pos = 0; // where the next element will be added
    cb->rempos = 0; // where the next element will be taken from

	if (cb->is_waiting) mutex_signal(&cb->locker);

	critical_leave(&cb->mutex);
}
Ejemplo n.º 7
0
Archivo: ipv4.c Proyecto: vladsor/chaos
static ipv4_interface_type *interface_get (char *identification)
{
  ipv4_interface_list_type *entry;

  mutex_wait (interface_list_mutex);
  entry = interface_list;

  while (entry != NULL)
  {
    if (string_compare (entry->interface->identification, identification) == 0)
    {
      mutex_signal (interface_list_mutex);
      return entry->interface;
    }

    entry = (ipv4_interface_list_type *) entry->next;
  }

  mutex_signal (interface_list_mutex);

  return NULL;
}
Ejemplo n.º 8
0
void cb_free(CircBuff_t * cb) {
	if (cb->invalid) return;

	critical_enter(&cb->mutex);
	free((void *) cb->buffer);
	cb->invalid = 1;

	if (cb->is_waiting) mutex_signal(&cb->locker);

	critical_leave(&cb->mutex);

    mutex_free(&cb->locker);
    mutex_free(&cb->mutex);

}
Ejemplo n.º 9
0
Archivo: ipv4.c Proyecto: vladsor/chaos
static void interface_add (ipv4_interface_type *interface,
                           ipc_structure_type *ethernet_structure)
{
  ipv4_interface_list_type *entry;

  memory_allocate ((void **) &entry, sizeof (ipv4_interface_list_type));
  entry->interface = interface;
  entry->ethernet_structure = ethernet_structure;

  /* Add this entry into the list. */

  mutex_wait (interface_list_mutex);
  entry->next = (struct ipv4_interface_list_type *) interface_list;
  interface_list = entry;
  mutex_signal (interface_list_mutex);
}
Ejemplo n.º 10
0
static void
tcp_stream_close (tcp_stream_t *u)
{
    tcp_socket_t*  s = u->socket;
	if (s) {
	mutex_lock (&s->lock);
	mutex_signal (&s->lock, 0);
	mutex_unlock (&s->lock);

	tcp_close (s);
	mem_free (s);
	u->socket = 0;
	}

	mem_free(u->outdata);
	u->outdata = 0;
}
Ejemplo n.º 11
0
/*
 * Задача выдачи статистики на консоль.
 */
void console (void *arg)
{
	unsigned t0;

	for (;;) {
		t0 = mips_read_c0_register (C0_COUNT);
		mutex_signal (&mailbox, (void*) t0);

		debug_puts ("\33[H");
		debug_puts ("Measuring task switch time.\n\n");

		debug_printf ("Task switches: %u  \n\n", nmessages);

		print_rational (" Latency, min: ", latency_min * 1000, KHZ);
		print_rational ("          max: ", latency_max * 1000, KHZ);
	}
}
Ejemplo n.º 12
0
Archivo: ipv4.c Proyecto: vladsor/chaos
static unsigned int interface_get_amount (void)
{
  ipv4_interface_list_type *entry;
  unsigned int counter = 0;

  mutex_wait (interface_list_mutex);
  entry = interface_list;

  while (entry != NULL)
  {
    counter++;
    entry = (ipv4_interface_list_type *) entry->next;
  }

  mutex_signal (interface_list_mutex);

  return counter;
}
Ejemplo n.º 13
0
/*
 * Задача выдачи статистики на консоль.
 */
void console (void *arg)
{
	unsigned t0;

	for (;;) {
		t0 = ARM_SYSTICK->VAL;
		mutex_signal (&mailbox, (void*) t0);

		gpanel_move (&display, 0, 0);
		printf (&display, "CPU: %u MHz\n\n", KHZ / 1000);

		printf (&display, "Task switches: %u\n\n", nmessages);

		if (nmessages > 100) {
			printf (&display, "Task switch time:\n");
			print_rational ("  min: ", latency_min * 1000, KHZ);
			print_rational ("  max: ", latency_max * 1000, KHZ);
		}
	}
}
Ejemplo n.º 14
0
DECLARE_TEST( mutex, signal )
{
	mutex_t* mutex;
	object_t thread[32];
	int ith;

	mutex = mutex_allocate( "test" );
	mutex_lock( mutex );

	for( ith = 0; ith < 32; ++ith )
	{
		thread[ith] = thread_create( thread_wait, "thread_wait", THREAD_PRIORITY_NORMAL, 0 );
		thread_start( thread[ith], mutex );
	}

	mutex_unlock( mutex );

	test_wait_for_threads_startup( thread, 32 );

	while( atomic_load32( &thread_waiting ) < 32 )
		thread_yield();
	thread_sleep( 1000 ); //Hack wait to give threads time to progress from atomic_incr to mutex_wait

	mutex_signal( mutex );

	for( ith = 0; ith < 32; ++ith )
	{
		thread_terminate( thread[ith] );
		thread_destroy( thread[ith] );
	}

	test_wait_for_threads_exit( thread, 32 );

	EXPECT_EQ( atomic_load32( &thread_waited ), 32 );

	EXPECT_FALSE( mutex_wait( mutex, 500 ) );

	mutex_deallocate( mutex );

	return 0;
}
Ejemplo n.º 15
0
static void
uartx_interrupt (uartx_t *u)
{
	u->lsr = UARTX_LSR (u->port);
	/*debug_printf ("lsr%d=%02x; ", u->port, u->lsr);*/

	if (u->lsr & MC_LSR_FE) {
		u->frame_errors++;
	}
	if (u->lsr & MC_LSR_PE) {
		u->parity_errors++;
	}
	if (u->lsr & MC_LSR_OE) {
		u->overruns++;
	}
	if (u->lsr & MC_LSR_BI) {
		/*debug_printf ("BREAK DETECTED\n");*/
	}
	uartx_transmit_start (u);

	/* Check that receive data is available,
	 * and get the received byte. */
	if (u->lsr & MC_LSR_RXRDY) {
		unsigned c = UARTX_RBR (u->port);

		unsigned char *newlast = u->in_last + 1;
		if (newlast >= u->in_buf + UART_INBUFSZ)
			newlast = u->in_buf;

		/* Ignore input on buffer overflow. */
		if (u->in_first != newlast) {
			*u->in_last = c;
			u->in_last = newlast;
		} else
			u->overruns++;
		mutex_signal (&u->receiver, 0);
	}
}
Ejemplo n.º 16
0
DECLARE_TEST(mutex, signal) {
	mutex_t* mutex;
	thread_t thread[32];
	size_t ith;

	mutex = mutex_allocate(STRING_CONST("test"));
	mutex_lock(mutex);

	for (ith = 0; ith < 32; ++ith)
		thread_initialize(&thread[ith], thread_waiter, mutex, STRING_CONST("thread_wait"),
		                  THREAD_PRIORITY_NORMAL, 0);
	for (ith = 0; ith < 32; ++ith)
		thread_start(&thread[ith]);

	mutex_unlock(mutex);

	test_wait_for_threads_startup(thread, 32);

	while (atomic_load32(&thread_waiting) < 32)
		thread_yield();
	thread_sleep(1000);   //Hack wait to give threads time to progress from atomic_incr to mutex_wait

	mutex_signal(mutex);

	test_wait_for_threads_finish(thread, 32);

	for (ith = 0; ith < 32; ++ith)
		thread_finalize(&thread[ith]);

	EXPECT_EQ(atomic_load32(&thread_waited), 32);

	EXPECT_FALSE(mutex_try_wait(mutex, 500));

	mutex_deallocate(mutex);

	return 0;
}
Ejemplo n.º 17
0
Archivo: ipv4.c Proyecto: vladsor/chaos
static ipv4_interface_type *interface_get_number (unsigned int number)
{
  ipv4_interface_list_type *entry;
  unsigned int counter = 0;

  mutex_wait (interface_list_mutex);
  entry = interface_list;

  while (entry != NULL && counter < number)
  {
    counter++;
    entry = (ipv4_interface_list_type *) entry->next;
  }

  mutex_signal (interface_list_mutex);
  if (entry == NULL)
  {
    return NULL;
  }
  else
  {
    return entry->interface;
  }
}
Ejemplo n.º 18
0
void put_forks (mutex_t *left_fork, mutex_t *right_fork)
{
	mutex_unlock (left_fork);
	mutex_unlock (right_fork);
	mutex_signal (&table, 0);
}
Ejemplo n.º 19
0
int cb_add(CircBuff_t * cb, float * in, const size_t len) {
	if (cb->invalid) return CB_ERROR;
    if (len <= 0) return CB_OK; // handle edge case

    critical_enter(&cb->mutex);

#if ASSERT_ENABLED
    assert(((cb->pos + cb->remaining_capacity) % cb->buffer_size) == cb->rempos);
#endif

    // if the size of the buffer is not large enough, request the buffer to be resized
    if (len*cb->size_coeff > cb->buffer_size) cb->desired_buf_size = len*cb->size_coeff;

    if (cb->buffer_size < cb->desired_buf_size) {
    	const size_t items_inside = cb->buffer_size - cb->remaining_capacity;
    	const size_t inflation = cb->desired_buf_size - cb->buffer_size;

        // if we need to resize the buffer, reset it
        cb->buffer = (float *) realloc((void *) cb->buffer, sizeof(float) * cb->desired_buf_size); // reallocate

        if (cb->rempos >= cb->pos) {
        	memmove((void *) &cb->buffer[cb->rempos+inflation], (void *) &cb->buffer[cb->rempos], sizeof(float) * (cb->buffer_size-cb->rempos));
        	if (items_inside != 0) cb->rempos += inflation;
        }

        cb->remaining_capacity += inflation;

        cb->buffer_size = cb->desired_buf_size; // set the size

#if ASSERT_ENABLED
        assert(cb->buffer_size - cb->remaining_capacity == items_inside);
#endif
    }

    if (cb->buffering && cb->remaining_capacity < 2*len) {
    	cb->buffering = 0;
    	critical_leave(&cb->mutex);
    	return CB_FULL; // if there is not enough space to put buffer, return error
    } else if (cb->remaining_capacity < len) {
    	cb->buffering = 1;
    	if (cb->size_coeff < cb->max_size_coeff) cb->size_coeff++;
        critical_leave(&cb->mutex);
        return CB_FULL; // if there is not enough space to put buffer, return error
    }

    const size_t oldpos = cb->pos;
    cb->pos = (oldpos + len) % cb->buffer_size; // calculate new position
    cb->remaining_capacity -= len; // the remaining capacity is reduced

    if (cb->pos <= oldpos) {
        // the add will wrap around
        const size_t remaining = cb->buffer_size - oldpos;
        memcpy((void *) &cb->buffer[oldpos], in, remaining * sizeof(float));
        memcpy((void *) cb->buffer, &in[remaining], cb->pos * sizeof(float));
    } else {
        // the add will not wrap around
        memcpy((void *) &cb->buffer[oldpos], in, len*sizeof(float));
    }

    if (cb->is_waiting) mutex_signal(&cb->locker);

    critical_leave(&cb->mutex);

    return CB_OK;
}