コード例 #1
0
/***********************************************************
 * Name: os_cond_wait
 *
 * Arguments:  OS_COND_T *cond,
 *             OS_SEMAPHORE_T *semaphore
 *
 * Description: Routine to wait for a condition variable
 *              to be signalled. Semaphore is released
 *              while waiting. The same semaphore must
 *              always be used.
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_cond_wait( OS_COND_T *cond, OS_SEMAPHORE_T *semaphore )
{
   int32_t success = -1;
    
   if (cond && semaphore)
   {
      COND_WAITER_T w;
      COND_WAITER_T *p, **prev;
       
      // Check the API is being followed
      os_assert((*cond)->semaphore == semaphore && os_semaphore_obtained(semaphore));
      
      // Fill in a new waiter structure allocated on our stack
      w.next = NULL;
      vcos_demand(vcos_event_create(&w.latch, NULL) == VCOS_SUCCESS);
      
      // Add it to the end of the condvar's wait queue (we wake first come, first served)
      prev = &(*cond)->waiters;
      p = (*cond)->waiters;
      while (p)
         prev = &p->next, p = p->next;
      *prev = &w;

      // Ready to go to sleep now
      success = os_semaphore_release(semaphore);
      os_assert(success == 0);

      vcos_event_wait(&w.latch);

      success = os_semaphore_obtain(semaphore);
      os_assert(success == 0);
   }
   
   return success;
}
コード例 #2
0
//Unlock the host state
static void lock_release (void) {
   int32_t success;
   vcos_assert(cecservice_client.initialised);
   vcos_assert(os_semaphore_obtained(&cecservice_client.sema));
   success = os_semaphore_release( &cecservice_client.sema );
   vcos_assert( success >= 0 );
}
コード例 #3
0
ファイル: vcilcs_vchi.c プロジェクト: kzlin129/tt-gpl
/* ----------------------------------------------------------------------
 * called from the vchi layer whenever an event happens.
 * here, we are only interested in the 'message available' callback
 * -------------------------------------------------------------------- */
static void
vc_ilcs_callback( void *callback_param,
                  const VCHI_CALLBACK_REASON_T reason,
                  void *msg_handle )
{
   int32_t success;
   OS_SEMAPHORE_T *sem;

   switch( reason ) {

   case VCHI_CALLBACK_MSG_AVAILABLE:
      sem = (OS_SEMAPHORE_T *)callback_param;
      if ( sem == NULL )
         break;;
      if ( os_semaphore_obtained(sem) ) {
         success = os_semaphore_release( sem );
         assert( success >= 0 );
      }
      break;

#if 0
   case VCHI_CALLBACK_BULK_RECEIVED:
   case VCHI_CALLBACK_BULK_SENT:
      sem = (OS_SEMAPHORE_T *)msg_handle;
      success = os_semaphore_release( sem );
      assert( success >= 0 );
      break;
#endif
   }
}
コード例 #4
0
ファイル: osal_test.c プロジェクト: cgjones/brcm_usrlib_dag
void ThreadCheck()
{
   VCOS_THREAD_T thread;

   // First create a sync semaphore   
   TEST_OK("os_semaphore_create", os_semaphore_create(&sem1, OS_SEMAPHORE_TYPE_SUSPEND));

   // and grab it   
   TEST_OK("os_semaphore_obtain", os_semaphore_obtain(&sem1));
   
   // Start the thread which shuold stall on the semaphore
   TEST_OK("os_thread_start", os_thread_start( &thread, &ThreadOne, NULL, 1000, "ThreadOne"));

   // Wait for thread to start for 1000 - should stall on semaphore and not change flag
   TEST_OK("os_delay", os_delay(1000));

   // Check global data is unchanged
   TEST_OK("Flag = 0", flag);

   // release semaphore
   TEST_OK("os_semaphore_release", os_semaphore_release(&sem1));
   
   // Wait for thread to continue for 100 - should be enough for it to set the flag

   TEST_OK("os_delay", os_delay(100));

   // Check global data is changed to non-zero
   TEST_OK("Flag = 1", (flag == 0));
   
   // Semaphore is currently released, so check the obtained function is correct.
   TEST_OK("os_semaphore_obtained - 0", os_semaphore_obtained(&sem1))
   
   // now get the sema and test again
   TEST_OK("os_semaphore_obtain", os_semaphore_obtain(&sem1));
   
   TEST_OK("os_semaphore_obtained - 1", (os_semaphore_obtained(&sem1) == 0))
   
   TEST_OK("os_semaphore_release", os_semaphore_release(&sem1));
}
コード例 #5
0
/***********************************************************
 * Name: hostreq_client_callback
 *
 * Arguments: semaphore, callback reason and message handle
 *
 * Description: VCHI callback for the HOSTREQ service
 *
 ***********************************************************/
static void hostreq_client_callback( void *callback_param,
                                      const VCHI_CALLBACK_REASON_T reason,
                                      void *msg_handle ) {

   OS_SEMAPHORE_T *sem = (OS_SEMAPHORE_T *)callback_param;
   if ( reason != VCHI_CALLBACK_MSG_AVAILABLE )
      return;

   if ( sem == NULL )
      return;

   if ( os_semaphore_obtained(sem) ) {
      int32_t success = os_semaphore_release( sem );
      assert( success >= 0 );
   }
}
コード例 #6
0
static void lock_release (void) {
   int32_t success;
   assert(os_semaphore_obtained(&gencmd_client.sema));
   success = os_semaphore_release( &gencmd_client.sema );
   assert( success >= 0 );
}
コード例 #7
0
ファイル: vcilcs_vchi.c プロジェクト: kzlin129/tt-gpl
/* ----------------------------------------------------------------------
 * send a string to the host side IL component service.  if resp is NULL
 * then there is no response to this call, so we should not wait for one.
 *
 * returns response, written to 'resp' pointer
 * -------------------------------------------------------------------- */
void
vc_ilcs_execute_function( IL_FUNCTION_T func, void *data, int len, void *data2, int len2, void *resp, int resplen )
{
   VC_ILCS_WAIT_T *wait;
   int num;

   // the host MUST receive a response
   assert( resp );

   // need to atomically find free ->wait entry
   os_semaphore_obtain( &vc_ilcsg.wait_sem );

   for (;;) {
      num = 0;

      while( num < VC_ILCS_MAX_WAITING && vc_ilcsg.wait[num].resp )
         num++;

      if ( num < VC_ILCS_MAX_WAITING )
         break;

      assert( num < VC_ILCS_MAX_WAITING );
      // might be a fatal error if another thread is relying
      // on this call completing before it can complete
      // we'll pause until we can carry on and hope that's sufficient.
      os_semaphore_release( &vc_ilcsg.wait_sem );
      os_sleep( 10 ); // 10 msec
      os_semaphore_obtain( &vc_ilcsg.wait_sem );
   }
   wait = &vc_ilcsg.wait[num];

   wait->resp = resp;
   wait->xid = vc_ilcsg.next_xid++;
   os_semaphore_create( &wait->sem, OS_SEMAPHORE_TYPE_SUSPEND );
   os_semaphore_obtain( &wait->sem );

   // at this point, ->wait is exclusively ours ()
   os_semaphore_release( &vc_ilcsg.wait_sem );

   // write the command header.
   vc_ilcs_transmit( func, wait->xid, data, len, data2, len2 );

   if ( !os_thread_current(vc_ilcsg.thread) ) {

      os_semaphore_obtain( &wait->sem );

   } else {

      // we're the vcilcs task, so wait for, and handle, incoming
      // messages while we're not completed
      for (;;) {

         // wait->sem will not be released until we process the response message
         if ( vc_ilcs_process_message() == 0 ) {
            // there were no more messages in the fifo; need to wait
            os_semaphore_obtain( &vc_ilcsg.rxmsg_sem );
            continue;
         }

         // did the last message release wait->sem ?
         if ( !os_semaphore_obtained(&wait->sem) )
            break;
      }
   }

   // safe to do the following - the assignment of NULL is effectively atomic
   os_semaphore_destroy( &wait->sem );
   wait->resp = NULL;
}
コード例 #8
0
ファイル: vcilcs_vchi.c プロジェクト: cgjones/brcm_usrlib_dag
/* ----------------------------------------------------------------------
 * send a string to the host side IL component service.  if resp is NULL
 * then there is no response to this call, so we should not wait for one.
 *
 * returns 0 on successful call made, -1 on failure to send call.
 * on success, the response is written to 'resp' pointer
 * -------------------------------------------------------------------- */
int vc_ilcs_execute_function( IL_FUNCTION_T func, void *data, int len, void *data2, int len2, void *bulk, int bulk_len, void *resp )
{
   VC_ILCS_WAIT_T *wait;
   int i, num;

   // the host MUST receive a response
   vc_assert( resp );

   // need to atomically find free ->wait entry
   os_semaphore_obtain( &vc_ilcsg.wait_sem );

   // we try a number of times then give up with an error message
   // rather than just deadlocking
   for (i=0; i<VC_ILCS_WAIT_TIMEOUT; i++) {
      num = 0;

      while( num < VC_ILCS_MAX_WAITING && vc_ilcsg.wait[num].resp )
         num++;

      if ( num < VC_ILCS_MAX_WAITING || i == VC_ILCS_WAIT_TIMEOUT-1)
         break;

      // might be a fatal error if another thread is relying
      // on this call completing before it can complete
      // we'll pause until we can carry on and hope that's sufficient.
      os_semaphore_release( &vc_ilcsg.wait_sem );
      os_sleep( 10 ); // 10 msec

      // if we're the vcilcs thread, then the waiters might need
      // us to handle their response, so try and clear those now
      if(os_thread_is_running(&vc_ilcsg.thread))
         while(vc_ilcs_process_message(0));

      os_logging_message( "%s: wait for sem", __FUNCTION__);
      os_semaphore_obtain( &vc_ilcsg.wait_sem );
   }

   if(num == VC_ILCS_MAX_WAITING)
   {
      // failed to send message.
      vc_assert(0);
      os_semaphore_release( &vc_ilcsg.wait_sem );
      return -1;
   }

   wait = &vc_ilcsg.wait[num];

   wait->resp = resp;
   wait->xid = vc_ilcsg.next_xid++;
   os_semaphore_create( &wait->sem, OS_SEMAPHORE_TYPE_SUSPEND );
   os_semaphore_obtain( &wait->sem );

   // at this point, ->wait is exclusively ours ()
   os_semaphore_release( &vc_ilcsg.wait_sem );

   if(bulk)
      os_semaphore_obtain( &vc_ilcsg.send_sem);

   // write the command header.
   vc_ilcs_transmit( func, wait->xid, data, len, data2, len2 );

   if(bulk)
   {
      int result;
      result = vchi_bulk_queue_transmit( vc_ilcsg.vchi_handle,                // call to VCHI
                                         bulk, bulk_len,
                                         VCHI_FLAGS_BLOCK_UNTIL_QUEUED,
                                         NULL );
      vc_assert(result == 0);
      os_semaphore_release( &vc_ilcsg.send_sem);
   }

   if ( !os_thread_is_running(&vc_ilcsg.thread) ) {

      os_semaphore_obtain( &wait->sem );

   } else {

      // we're the vcilcs task, so wait for, and handle, incoming
      // messages while we're not completed
      for (;;) {
         // wait->sem will not be released until we process the response message
         vc_ilcs_process_message(1);

         // did the last message release wait->sem ?
         if ( !os_semaphore_obtained(&wait->sem) )
            break;
      }
   }

   // safe to do the following - the assignment of NULL is effectively atomic
   os_semaphore_destroy( &wait->sem );
   wait->resp = NULL;
   return 0;
}
コード例 #9
0
//Unlock the host state
static void lock_release (void) {
   assert(hostreq_client.initialised);
   assert(os_semaphore_obtained(&hostreq_client.sema));
   int32_t success = os_semaphore_release(&hostreq_client.sema);
   assert( success >= 0 );
}
コード例 #10
0
//Lock the host state
static void lock_obtain (void) {
   assert(hostreq_client.initialised);
   assert(!os_semaphore_obtained(&hostreq_client.sema));
   int success = os_semaphore_obtain(&hostreq_client.sema);
   assert(success >= 0);
}