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; }
/* * 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); } }
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; }
/* * 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); }
/* * 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; }
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); }
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; }
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); }
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); }
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; }
/* * Задача выдачи статистики на консоль. */ 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); } }
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; }
/* * Задача выдачи статистики на консоль. */ 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); } } }
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; }
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); } }
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; }
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; } }
void put_forks (mutex_t *left_fork, mutex_t *right_fork) { mutex_unlock (left_fork); mutex_unlock (right_fork); mutex_signal (&table, 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; }