static void entry0( cyg_addrword_t data ) { cyg_count32 val; cyg_semaphore_wait(&s0); CHECK( 1 == q++ ); cyg_semaphore_post(&s1); cyg_semaphore_wait(&s0); CHECK( 3 == q++ ); cyg_semaphore_peek(&s0, &val); CHECK( 0 == val); CHECK( ! cyg_semaphore_trywait(&s0) ); cyg_semaphore_post(&s0); CHECK( 4 == q++ ); cyg_semaphore_peek(&s0, &val); CHECK( 1 == val); cyg_semaphore_post(&s0); cyg_semaphore_peek(&s0, &val); CHECK( 2 == val); cyg_semaphore_post(&s1); cyg_semaphore_peek(&s2, &val); CHECK( 0 == val); cyg_semaphore_wait(&s2); CHECK( 6 == q++ ); CYG_TEST_PASS_FINISH("Kernel C API Semaphore 1 OK"); }
static void entry1( cyg_addrword_t data ) { cyg_count32 val; cyg_semaphore_peek(&s1, &val); CHECK( 2 == val); cyg_semaphore_wait(&s1); cyg_semaphore_peek(&s1, &val); CHECK( 1 == val); cyg_semaphore_wait(&s1); CHECK( 0 == q++ ); cyg_semaphore_peek(&s0, &val); CHECK( 0 == val); cyg_semaphore_post(&s0); cyg_semaphore_wait(&s1); CHECK( 2 == q++ ); cyg_semaphore_post(&s0); cyg_semaphore_wait(&s1); CHECK( 5 == q++ ); cyg_semaphore_peek(&s0, &val); CHECK( 2 == val); CHECK( cyg_semaphore_trywait(&s0) ); cyg_semaphore_peek(&s0, &val); CHECK( 1 == val); CHECK( cyg_semaphore_trywait(&s0) ); cyg_semaphore_peek(&s0, &val); CHECK( 0 == val); cyg_semaphore_post(&s2); cyg_semaphore_wait(&s0); CYG_TEST_FAIL_FINISH("Not reached"); }
void Philosopher( cyg_addrword_t vid ) { cyg_uint32 id = (cyg_uint32)vid; cyg_sem_t *first_stick = &chopstick[id]; cyg_sem_t *second_stick = &chopstick[(id+1)%PHILOSOPHERS]; #ifdef CYGPKG_INFRA_DEBUG int left_philo = ((id==0)?PHILOSOPHERS:id)-1; int right_philo = (id==PHILOSOPHERS-1)?0:(id+1); #endif CYG_ASSERT( id >= 0 && id < PHILOSOPHERS, "Bad id"); // Deadlock avoidance. The easiest way to make the philosophers // behave is to make each pick up the lowest numbered stick // first. This is how it works out anyway for all the philosophers // except the last, who must have his sticks swapped. if( id == PHILOSOPHERS-1 ) { cyg_sem_t *t = first_stick; first_stick = second_stick; second_stick = t; } for(;;) { cyg_ucount32 val; // The following variable is shared by all philosophers. // It is incremented unprotected, but this does not matter // since it is only present to introduce a little variability // into the think and eat times. static volatile int cycle = 0; // Think for a bit cyg_thread_delay((id+cycle++)%12); // Cogito ergo sum... // I am now hungry, try to get the chopsticks change_state(id,'H'); // Get the first stick cyg_semaphore_wait(first_stick); // Get the second stick cyg_semaphore_wait(second_stick); // Got them, now eat change_state(id,'E'); // Check that the world is as I think it is... cyg_semaphore_peek( first_stick, &val); CYG_ASSERT( val == 0, "Not got first stick"); cyg_semaphore_peek( second_stick, &val); CYG_ASSERT( val == 0, "Not got second stick"); CYG_ASSERT( get_state(left_philo) != 'E', "Left neighbour also eating!!"); CYG_ASSERT( get_state(right_philo) != 'E', "Right neighbour also eating!!"); cyg_thread_delay((id+cycle++)%6); // munch munch // Finished eating, put down sticks. change_state(id,'T'); cyg_semaphore_post( first_stick ); cyg_semaphore_post( second_stick ); } }
static void master(cyg_addrword_t param) { int i; cyg_handle_t self = cyg_thread_self(); cyg_semaphore_init( &send_sema, 0 ); cyg_semaphore_init( &recv_sema, 0 ); for ( i = 0 ; i < NLISTENERS; i++ ) cyg_semaphore_init( &listen_sema[i], 0 ); init_all_network_interfaces(); CYG_TEST_INFO("Start multiple loopback select test"); #if NLOOP > 0 // We are currently running at high prio, so we can just go and make // loads of threads: // Some at higher prio for ( i = 0; i < NLISTENERS/2; i++ ) cyg_thread_create(PRIO_LISTENER_HI, // Priority listener, // entry i, // entry parameter "listener", // Name &stack_listener[i][0], // Stack STACK_SIZE, // Size &listener_thread_handle[i], // Handle &listener_thread_data[i] // Thread data structure ); // the rest at lower prio for ( ; i < NLISTENERS ; i++ ) cyg_thread_create(PRIO_LISTENER_LO, // Priority listener, // entry i, // entry parameter "listener", // Name &stack_listener[i][0], // Stack STACK_SIZE, // Size &listener_thread_handle[i], // Handle &listener_thread_data[i] // Thread data structure ); // make the dummy event-grabber threads for ( i = 0; i < NDUMMIES; i++ ) cyg_thread_create(PRIO_DUMMY, // Priority dummy, // entry i, // entry parameter "dummy", // Name &stack_dummy[i][0], // Stack STACK_SIZE, // Size &dummy_thread_handle[i], // Handle &dummy_thread_data[i] // Thread data structure ); // Start those threads for ( i = 0; i < NLISTENERS; i++ ) cyg_thread_resume(listener_thread_handle[i]); for ( i = 0; i < NDUMMIES; i++ ) cyg_thread_resume( dummy_thread_handle[i]); // and let them start up and start listening... cyg_thread_set_priority( self, PRIO_MASTERLOW ); CYG_TEST_INFO("All listeners should be go now"); cyg_thread_set_priority( self, PRIO_MASTERHIGH ); for ( i = 0; i < NSENDERS; i++ ) { cyg_thread_create( (0 == i) ?PRIO_SENDER_MID : PRIO_SENDER_LOW, // Priority sender, // entry i, // entry parameter "sender", // Name &stack_sender[i][0], // Stack STACK_SIZE, // Size &sender_thread_handle[i], // Handle &sender_thread_data[i] // Thread data structure ); cyg_thread_resume(sender_thread_handle[i]); } // Now we are still higher priority; so go low and let everyone else // have their head. When we next run after this, it should all be // over. cyg_thread_set_priority( self, PRIO_MASTERLOW ); cyg_semaphore_peek( &recv_sema, &i ); CYG_TEST_CHECK( NLISTENERS == i, "Not enough recvs occurred!" ); cyg_semaphore_peek( &send_sema, &i ); CYG_TEST_CHECK( NLISTENERS == i, "Not enough sends occurred!" ); CYG_TEST_PASS_FINISH("Master returned OK"); #endif CYG_TEST_NA( "No loopback devs" ); }