示例#1
0
void vcos_log_unregister(VCOS_LOG_CAT_T *category)
{
   VCOS_LOG_CAT_T **pcat;

   vcos_mutex_lock(&lock);
   category->refcount--;
   if (category->refcount == 0)
   {
      pcat = &vcos_logging_categories;
      while (*pcat != category)
      {
         if (!*pcat)
            break;   /* possibly deregistered twice? */
         if ((*pcat)->next == NULL)
         {
            vcos_assert(0); /* already removed! */
            vcos_mutex_unlock(&lock);
            return;
         }
         pcat = &(*pcat)->next;
      }
      if (*pcat)
         *pcat = category->next;

      vcos_log_platform_unregister(category);
   }
   vcos_mutex_unlock(&lock);
}
示例#2
0
/** Send a message and do not wait for a reply.
  *
  * @note
  * This function should only be called from within a mmal component, so
  * vchiq_use/release_service calls aren't required (dealt with at higher level).
  *
  * @param client       client to send message for
  * @param msg_header   message header to send
  * @param size         length of message, including header
  * @param msgid        message id
  */
MMAL_STATUS_T mmal_vc_send_message(MMAL_CLIENT_T *client,
                                   mmal_worker_msg_header *msg_header, size_t size,
                                   uint8_t *data, size_t data_size,
                                   uint32_t msgid)
{
   VCHIQ_STATUS_T vst;
   VCHIQ_ELEMENT_T elems[] = {{msg_header, size}};
   MMAL_BOOL_T using_bulk_transfer = (data_size != 0);

   LOG_TRACE("len %d", data_size);
   vcos_assert(size >= sizeof(mmal_worker_msg_header));

   if (!client->inited)
   {
      vcos_assert(0);
      return MMAL_EINVAL;
   }

   if (using_bulk_transfer)
      vcos_mutex_lock(&client->bulk_lock);

   msg_header->msgid  = msgid;
   msg_header->magic  = MMAL_MAGIC;

   vst = vchiq_queue_message(client->service, elems, 1);

   if (vst != VCHIQ_SUCCESS)
   {
      if (using_bulk_transfer)
         vcos_mutex_unlock(&client->bulk_lock);

      LOG_ERROR("failed");
      goto error;
   }

   if (using_bulk_transfer)
   {
      LOG_TRACE("bulk transmit: %p, %i", data, data_size);

      data_size = (data_size + 3) & ~3;
      vst = vchiq_queue_bulk_transmit(client->service, data, data_size, msg_header);

      vcos_mutex_unlock(&client->bulk_lock);

      if (!vcos_verify(vst == VCHIQ_SUCCESS))
      {
         LOG_ERROR("failed bulk transmit");
         /* This really should not happen and if it does, things will go wrong as
          * we've already queued the vchiq message above. */
         vcos_assert(0);
         goto error;
      }
   }

   return MMAL_SUCCESS;

 error:
   return MMAL_EIO;
}
示例#3
0
int32_t vc_gpuserv_init( void )
{
   VCHIQ_SERVICE_PARAMS_T vchiq_params;
   VCOS_STATUS_T status = VCOS_ENXIO;
   VCHIQ_STATUS_T vchiq_status;

   vcos_once(&gpuserv_client_once, init_once);

   vcos_mutex_lock(&gpuserv_client.lock);

   if (gpuserv_client.refcount++ > 0)
   {
      /* Already initialised so nothing to do */
      vcos_mutex_unlock(&gpuserv_client.lock);
      return VCOS_SUCCESS;
   }

   vcos_log_set_level(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE);
   vcos_log_register("gpuserv", VCOS_LOG_CATEGORY);

   vcos_log_trace("%s: starting initialisation", VCOS_FUNCTION);

   /* Initialise a VCHIQ instance */
   vchiq_status = vchiq_initialise(&gpuserv_client_vchiq_instance);
   if (vchiq_status != VCHIQ_SUCCESS)
   {
      vcos_log_error("%s: failed to initialise vchiq: %d", VCOS_FUNCTION, vchiq_status);
      goto error;
   }

   vchiq_status = vchiq_connect(gpuserv_client_vchiq_instance);
   if (vchiq_status != VCHIQ_SUCCESS)
   {
      vcos_log_error("%s: failed to connect to vchiq: %d", VCOS_FUNCTION, vchiq_status);
      goto error;
   }

   memset(&vchiq_params, 0, sizeof(vchiq_params));
   vchiq_params.fourcc = VCHIQ_MAKE_FOURCC('G','P','U','S');
   vchiq_params.callback = gpuserv_callback;
   vchiq_params.userdata = NULL;
   vchiq_params.version = 1;
   vchiq_params.version_min = 1;

   vchiq_status = vchiq_open_service(gpuserv_client_vchiq_instance, &vchiq_params, &gpuserv_client.service);
   if (vchiq_status != VCHIQ_SUCCESS)
   {
      vcos_log_error("%s: could not open vchiq service: %d", VCOS_FUNCTION, vchiq_status);
      goto error;
   }
   vcos_mutex_unlock(&gpuserv_client.lock);
   return 0;
error:
   vcos_mutex_unlock(&gpuserv_client.lock);
   return -1;
}
VCOS_STATUS_T
vcos_generic_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count)
{
   VCOS_STATUS_T status;
   int i, name_len;

   vcos_mutex_lock(&lock);
   
   /* do we already have this semaphore? */

   for (i=0; i<MAX_SEMS; i++)
   {
      if (sems[i].refs && strcmp(name, sems[i].name) == 0)
      {
         sems[i].refs++;
         sem->actual = sems+i;
         sem->sem = &sems[i].sem;
         vcos_mutex_unlock(&lock);
         return VCOS_SUCCESS;
      }
   }

   /* search for unused semaphore */

   name_len = strlen(name);

   if (name_len >= VCOS_NAMED_SEMAPHORE_NAMELEN)
   {
      vcos_assert(0);
      vcos_mutex_unlock(&lock);
      return VCOS_EINVAL;
   }

   for (i=0; i<MAX_SEMS; i++)
   {
      if (sems[i].refs == 0)
      {
         status = vcos_semaphore_create(&sems[i].sem, name, count);
         if (status == VCOS_SUCCESS)
         {
            sems[i].refs = 1;
            strcpy(sems[i].name, name); /* already checked length! */
            sem->actual = sems+i;
            sem->sem = &sems[i].sem;
         }
         vcos_mutex_unlock(&lock);
         return status;
      }
   }

   vcos_mutex_unlock(&lock);

   return VCOS_ENOSPC;
}
示例#5
0
/* find a message queue, optionally blocking until it is created */
static VCOS_MSGQUEUE_T *vcos_msgq_find_helper(const char *name, int wait)
{
   VCOS_MSG_ENDPOINT_T *ep;
   VCOS_ENDPOINT_WAITER_T waiter;
   do
   {
      vcos_mutex_lock(&lock);
      for (ep = endpoints; ep != NULL; ep = ep->next)
      {
         if (strcmp(ep->name, name) == 0)
         {
            /* found it - return to caller */
            vcos_mutex_unlock(&lock);
            return &ep->primary;
         }
      }

      /* if we get here, we did not find it */
      if (!wait)
      {
         vcos_mutex_unlock(&lock);
         return NULL;
      }
      else
      {
         VCOS_STATUS_T st;
         waiter.name = name;
         st = vcos_semaphore_create(&waiter.sem,"vcos:waiter",0);
         if (st != VCOS_SUCCESS)
         {
            vcos_assert(0);
            vcos_mutex_unlock(&lock);
            return NULL;
         }

         /* Push new waiter onto head of global waiters list */
         /* coverity[use] Suppress ATOMICITY warning - 'waiters' might have
          * changed since the last iteration of the loop, which is okay */
         waiter.next = waiters;
         waiters = &waiter;

         /* we're now on the list, so can safely go to sleep */
         vcos_mutex_unlock(&lock);
         vcos_semaphore_wait(&waiter.sem);
         /* It should now be on the list, but it could in theory be deleted
          * between waking up and going to look for it. So may have to wait
          * again.
          * So, go round again....
          */
         vcos_semaphore_delete(&waiter.sem);
         continue;
      }
   } while (1);
}
示例#6
0
void vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args)
{
   (void)_level;

#ifdef ANDROID
   if ( vcos_use_android_log )
   {
      __android_log_vprint(log_prio[_level], cat->name, fmt, args);
   }
   else
   {
      vcos_mutex_lock(&printf_lock);
#endif
      if(NULL != log_fhandle)
      {
         if (cat->flags.want_prefix)
            fprintf( log_fhandle, "%s: ", cat->name );
         vfprintf(log_fhandle, fmt, args);
         fputs("\n", log_fhandle);
         fflush(log_fhandle);
      }
#ifdef ANDROID
      vcos_mutex_unlock(&printf_lock);
   }
#endif
}
示例#7
0
void *vcos_generic_blockpool_elem_from_handle(
      VCOS_BLOCKPOOL_T *pool, uint32_t handle)
{
   VCOS_BLOCKPOOL_SUBPOOL_T *subpool;
   uint32_t subpool_id;
   uint32_t index;
   void *ret = NULL;


   ASSERT_POOL(pool);
   vcos_mutex_lock(&pool->mutex);
   subpool_id = VCOS_BLOCKPOOL_HANDLE_GET_SUBPOOL(handle);

   if (subpool_id < pool->num_subpools)
   {
      index = VCOS_BLOCKPOOL_HANDLE_GET_INDEX(handle);
      subpool = &pool->subpools[subpool_id];
      if (pool->subpools[subpool_id].magic == VCOS_BLOCKPOOL_SUBPOOL_MAGIC &&
            pool->subpools[subpool_id].mem && index < subpool->num_blocks)
      {
         VCOS_BLOCKPOOL_HEADER_T *hdr = (VCOS_BLOCKPOOL_HEADER_T*)
            ((size_t) subpool->start + (index * pool->block_size));

         if (hdr->owner.subpool == subpool) /* Check block is allocated */
            ret = hdr + 1;
      }
   }
   vcos_mutex_unlock(&pool->mutex);

   vcos_log_trace("%s: pool %p handle 0x%08x elem %p", VCOS_FUNCTION, pool,
         handle, ret);
   return ret;
}
VCHIQ_STATUS_T vchiq_open_service(VCHIQ_INSTANCE_T instance, int fourcc, VCHIQ_CALLBACK_T callback, void *userdata, VCHIQ_SERVICE_HANDLE_T *pservice)
{
   VCHIQ_STATE_T *state = &instance->state;
   VCHIQ_SERVICE_T *service;
   VCHIQ_STATUS_T status = VCHIQ_ERROR;

   vcos_assert(fourcc != VCHIQ_FOURCC_INVALID);
   vcos_assert(callback != NULL);

   if (!is_valid_instance(instance))
      return VCHIQ_ERROR;

   if (!instance->connected)
      return VCHIQ_ERROR;

   vcos_mutex_lock(&state->mutex);

   service = vchiq_add_service_internal(state, fourcc, callback, userdata, VCHIQ_SRVSTATE_OPENING, instance);

   vcos_mutex_unlock(&state->mutex);

   if (service)
   {
      status = vchiq_open_service_internal(service);
      if (status != VCHIQ_SUCCESS)
      {
         vchiq_remove_service(&service->base);
         service = NULL;
      }
   }
   *pservice = &service->base;
   return status;
}
示例#9
0
/** Create a QUEUE of MMAL_BUFFER_HEADER_T */
MMAL_QUEUE_T *mmal_queue_create(void)
{
   MMAL_QUEUE_T *queue;

   queue = vcos_malloc(sizeof(*queue), "MMAL queue");
   if(!queue) return 0;

   if(vcos_mutex_create(&queue->lock, "MMAL queue lock") != VCOS_SUCCESS )
   {
      vcos_free(queue);
      return 0;
   }

   if(vcos_semaphore_create(&queue->semaphore, "MMAL queue sema", 0) != VCOS_SUCCESS )
   {
      vcos_mutex_delete(&queue->lock);
      vcos_free(queue);
      return 0;
   }

   /* gratuitous lock for coverity */ vcos_mutex_lock(&queue->lock);
   queue->length = 0;
   queue->first = 0;
   queue->last = &queue->first;
   mmal_queue_sanity_check(queue, NULL);
   /* gratuitous unlock for coverity */ vcos_mutex_unlock(&queue->lock);

   return queue;
}
示例#10
0
/* OMX_FreeHandle */
OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
   OMX_IN  OMX_HANDLETYPE hComponent)
{
   OMX_ERRORTYPE eError = OMX_ErrorNone;
   OMX_COMPONENTTYPE *pComp;

   if (hComponent == NULL || ilcs_service == NULL)
      return OMX_ErrorBadParameter;

   pComp = (OMX_COMPONENTTYPE*)hComponent;

   if (ilcs_service == NULL)
      return OMX_ErrorBadParameter;

   eError = (pComp->ComponentDeInit)(hComponent);
   if (eError == OMX_ErrorNone) {
      vcos_mutex_lock(&lock);
      --nActiveHandles;
      vcos_mutex_unlock(&lock);
      free(pComp);
   }

   vcos_assert(nActiveHandles >= 0);

   return eError;
}
示例#11
0
static void mmal_vc_payload_list_release(MMAL_VC_PAYLOAD_ELEM_T *elem)
{
   vcos_mutex_lock(&mmal_vc_payload_list.lock);
   elem->handle = elem->vc_handle = 0;
   elem->mem = 0;
   elem->in_use = 0;
   vcos_mutex_unlock(&mmal_vc_payload_list.lock);
}
示例#12
0
/** Set quit flag, with locking.
 * @param quit  New value of the quit flag: true - command thread to quit; false - command thread
 *              to continue.
 * @return Old value of the quit flag.
 */
static bool vidtex_set_quit(VIDTEX_T *vt, bool quit)
{
   vcos_mutex_lock(&vt->mutex);
   bool old_quit = vt->quit;
   vt->quit = quit;
   vcos_mutex_unlock(&vt->mutex);

   return old_quit;
}
示例#13
0
/** Get value of svp->stop, with locking. */
static uint32_t svp_get_stop(SVP_T *svp)
{
   uint32_t stop;

   vcos_mutex_lock(&svp->mutex);
   stop = svp->stop;
   vcos_mutex_unlock(&svp->mutex);

   return stop;
}
示例#14
0
VCOS_STATUS_T vcos_log_status_cmd( VCOS_CMD_PARAM_T *param )
{
   VCOS_LOG_CAT_T   *cat;
   VCOS_STATUS_T     status;

   vcos_mutex_lock(&lock);

   if ( param->argc == 1)
   {
      int   nw;
      int   nameWidth = 0;

      /* Print information about all of the categories. */

      for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
      {
         nw = (int)strlen( cat->name );

         if ( nw > nameWidth )
         {
            nameWidth = nw;
         }
      }

      for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
      {
         vcos_cmd_printf( param, "%-*s - %s\n", nameWidth, cat->name, vcos_log_level_to_string( cat->level ));
      }
   }
   else
   {
      /* Print information about a particular category */

      for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
      {
         if ( vcos_strcmp( cat->name, param->argv[1] ) == 0 )
         {
            vcos_cmd_printf( param, "%s - %s\n", cat->name, vcos_log_level_to_string( cat->level ));
            break;
         }
      }
      if ( cat == NULL )
      {
         vcos_cmd_printf( param, "Unrecognized logging category: '%s'\n", param->argv[1] );
         status = VCOS_ENOENT;
         goto out;
      }
   }

   status = VCOS_SUCCESS;
out:
   vcos_mutex_unlock(&lock);

   return status;
}
示例#15
0
//Unlock the host state
static __inline void lock_release (void) {
   uint32_t i;
   vcos_assert(dispmanx_client.initialised);
   if(dispmanx_client.initialised)
   {
      for (i=0; i<dispmanx_client.num_connections; i++) {
         vchi_service_release(dispmanx_client.client_handle[i]);
      }
   }
   vcos_mutex_unlock( &dispmanx_client.lock );
}
示例#16
0
void vc_gpuserv_deinit( void )
{
   vcos_mutex_lock(&gpuserv_client.lock);

   if (gpuserv_client.refcount > 0 && --gpuserv_client.refcount == 0)
   {
      vchi_service_close(gpuserv_client.service);
      gpuserv_client.service = 0;
   }
   vcos_mutex_unlock(&gpuserv_client.lock);
}
void vcos_generic_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m)
{
   vcos_assert(m->count != 0);
   vcos_assert(m->owner == vcos_thread_current());
   m->count--;
   if (m->count == 0)
   {
      m->owner = 0;
      vcos_mutex_unlock(&m->mutex);
   }
}
	void *CComponent::EventThreadProc(VCOS_EVENT_FLAGS_T& EventFlags, VCOS_EVENT_T& InitialzedEvent)
	{
		vcos_event_signal(&InitialzedEvent);
		VCOS_UNSIGNED nEvents;
		try
		{
			for (;;)
			{
				CHECK_VCOS(vcos_event_flags_get(&EventFlags, CThread::s_nTerminationFlag | s_nNewEventFlag, VCOS_CONSUME, VCOS_SUSPEND, &nEvents), "failed to wait for events");
				if (nEvents & CThread::s_nTerminationFlag)
				{
					// Component is being destoryed
					break;
				}
				else if (nEvents & s_nNewEventFlag)
				{
					// New event that cannot be handled in the notification callback
					bool bEventsPending = false;
					do
					{

						CComponentEvent Event;
						{
							CHECK_VCOS(vcos_mutex_lock(&m_EventQueueMutex), "failed to lock event queue mutex");
							Event = m_EventQueue.front();
							m_EventQueue.pop_front();
							bEventsPending = !m_EventQueue.empty();
							vcos_mutex_unlock(&m_EventQueueMutex);
						}
						switch (Event.m_EventType)
						{
						case OMX_EventPortSettingsChanged:
							{
								if (m_pGraph)
								{
									m_pGraph->OnPortSettingsChanged(this, Event.m_nData1);
								}
							}
							break;
						default:
							break;
						}
					}
					while (bEventsPending);
				}
			}
		}
		catch (std::exception& Exception)
		{
			std::cerr << "Error: " << Exception.what() << std::endl;
		}
		return NULL;
	}
示例#19
0
static void *mmal_playback(void *id)
{
   FILE_PLAY_INFO_T *play_info = id;
   MMALPLAY_OPTIONS_T opts;
   MMAL_STATUS_T status;
   MMALPLAY_T *ctx;

   /* Setup the options */
   opts = options;
   opts.output_uri = play_info->options.output_uri;
   opts.render_layer = play_info->options.render_layer;

   vcos_mutex_lock(&play_info->lock);
   ctx = mmalplay_create(play_info->uri, &opts, &status);
   play_info->ctx = ctx;
   vcos_mutex_unlock(&play_info->lock);
   if (!ctx)
      goto end;

   if (!opts.disable_playback)
      status = mmalplay_play(ctx);

   if (unclean_exit)
      goto end;

   vcos_mutex_lock(&play_info->lock);
   if (ctx)
   {
      /* coverity[use] Suppress ATOMICITY warning - ctx might have changed since
       * we initialised it above, which is okay */
      mmalplay_destroy(ctx);
   }
   play_info->ctx = 0;
   vcos_mutex_unlock(&play_info->lock);

 end:
   LOG_TRACE("Thread %s terminating, result %d", play_info->name, status);
   play_info->status = status;
   return NULL;
}
示例#20
0
/** Put a MMAL_BUFFER_HEADER_T back at the start of a QUEUE. */
void mmal_queue_put_back(MMAL_QUEUE_T *queue, MMAL_BUFFER_HEADER_T *buffer)
{
   if(!queue || !buffer) return;

   vcos_mutex_lock(&queue->lock);
   mmal_queue_sanity_check(queue, buffer);
   queue->length++;
   buffer->next = queue->first;
   queue->first = buffer;
   if(queue->last == &queue->first) queue->last = &buffer->next;
   vcos_semaphore_post(&queue->semaphore);
   vcos_mutex_unlock(&queue->lock);
}
void vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem)
{
   VCOS_NAMED_SEMAPHORE_IMPL_T *actual = sem->actual;
   vcos_mutex_lock(&lock);

   vcos_assert(actual->refs); /* if this fires, the semaphore has already been deleted */

   if (--actual->refs == 0)
   {
      vcos_semaphore_delete(&actual->sem);
   }
   vcos_mutex_unlock(&lock);
}
VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance)
{
   VCHIQ_STATUS_T status;

   if (!is_valid_instance(instance))
      return VCHIQ_ERROR;

   vcos_mutex_lock(&instance->state.mutex);
   status = vchiq_connect_internal(&instance->state, instance);
   if (status == VCHIQ_SUCCESS)
      instance->connected = 1;
   vcos_mutex_unlock(&instance->state.mutex);
   return status;
}
示例#23
0
void mmal_vc_deinit(void)
{
   int count;

   vcos_mutex_lock(&client.lock);
   count = --client.refcount;
   if (count != 0)
   {
      /* Still in use so don't do anything */
      vcos_mutex_unlock(&client.lock);
      return;
   }

   vcos_mutex_delete(&client.bulk_lock);
   destroy_waitpool(&client.waitpool);
   vchiq_close_service(client.service);
   vchiq_shutdown(mmal_vchiq_instance);
   vcos_log_unregister(VCOS_LOG_CATEGORY);

   client.service = VCHIQ_SERVICE_HANDLE_INVALID;
   client.inited = 0;
   vcos_mutex_unlock(&client.lock);
}
示例#24
0
VCOS_STATUS_T vcos_log_set_cmd( VCOS_CMD_PARAM_T *param )
{
   VCOS_LOG_CAT_T   *cat;
   char             *name;
   char             *levelStr;
   VCOS_LOG_LEVEL_T  level;
   VCOS_STATUS_T     status;

   if ( param->argc != 3 )
   {
      vcos_cmd_usage( param );
      return VCOS_EINVAL;
   }

   name = param->argv[1];
   levelStr = param->argv[2];

   if ( vcos_string_to_log_level( levelStr, &level ) != VCOS_SUCCESS )
   {
      vcos_cmd_printf( param, "Unrecognized logging level: '%s'\n", levelStr );
      return VCOS_EINVAL;
   }

   vcos_mutex_lock(&lock);

   status = VCOS_SUCCESS;
   for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
   {
      if ( vcos_strcmp( name, cat->name ) == 0 )
      {
         cat->level = level;
         vcos_cmd_printf( param, "Category %s level set to %s\n", name, levelStr );
         break;
      }
      else if ( vcos_strcmp( name, "*") == 0 )
      {
         cat->level = level;
         vcos_cmd_printf( param, "Category %s level set to %s\n", name, levelStr );
      }
   }
   if ( cat == NULL )
   {
      vcos_cmd_printf( param, "Unrecognized category: '%s'\n", name );
      status = VCOS_ENOENT;
   }

   vcos_mutex_unlock(&lock);

   return status;
}
示例#25
0
/* append a message to a message queue */
static void msgq_append(VCOS_MSGQUEUE_T *q, VCOS_MSG_T *msg)
{
   vcos_mutex_lock(&q->lock);
   if (q->head == NULL)
   {
      q->head = q->tail = msg;
   }
   else
   {
      q->tail->next = msg;
      q->tail = msg;
   }
   vcos_mutex_unlock(&q->lock);
}
示例#26
0
static MMAL_STATUS_T mmal_vc_release_internal(MMAL_CLIENT_T *client)
{
   MMAL_STATUS_T status = MMAL_SUCCESS;
   vcos_mutex_lock(&client->lock);
   if(--client->usecount == 0)
   {
      if(vchiq_release_service(client->service) != VCHIQ_SUCCESS)
      {
         client->usecount++;
         status = MMAL_EIO;
      }
   }
   vcos_mutex_unlock(&client->lock);
   return status;
}
/** Called when a get call times out. Remove this thread's
  * entry from the waiting queue, then resume the thread.
  */
static void event_flags_timer_expired(void *cxt)
{
   VCOS_EVENT_WAITER_T *waitreq = (VCOS_EVENT_WAITER_T *)cxt;
   VCOS_EVENT_FLAGS_T *flags = waitreq->flags;
   VCOS_EVENT_WAITER_T **plist;
   VCOS_EVENT_WAITER_T *prev = NULL;
   VCOS_THREAD_T *thread = 0;

   vcos_assert(flags);

   vcos_mutex_lock(&flags->lock);

   /* walk the list of waiting threads on this event group, and remove
    * the one that has expired.
    *
    * FIXME: could use doubly-linked list if lots of threads are found
    * to be waiting on a single event flag instance.
    */
   plist = &flags->waiters.head;
   while (*plist != NULL)
   {
      if (*plist == waitreq)
      {
         int at_end;
         /* found it */
         thread = (*plist)->thread;
         at_end = ((*plist)->next == NULL);

         /* link past */
         *plist = (*plist)->next;
         if (at_end)
            flags->waiters.tail = prev;

         break;
      }
      prev = *plist;
      plist = &(*plist)->next;
   }
   vcos_assert(waiter_list_valid(flags));

   vcos_mutex_unlock(&flags->lock);

   if (thread)
   {
      _vcos_thread_sem_post(thread);
   }
}
示例#28
0
/* wait on a queue for a message */
static _VCOS_INLINE
VCOS_MSG_T *vcos_msg_wait_helper(VCOS_MSGQUEUE_T *queue)
{
   VCOS_MSG_T *msg;
   vcos_semaphore_wait(&queue->sem);
   vcos_mutex_lock(&queue->lock);

   msg = queue->head;
   vcos_assert(msg);    /* should always be a message here! */

   queue->head = msg->next;
   if (queue->head == NULL)
      queue->tail = NULL;

   vcos_mutex_unlock(&queue->lock);
   return msg;
}
示例#29
0
/** Get a MMAL_BUFFER_HEADER_T from a QUEUE. Semaphore already claimed */
static MMAL_BUFFER_HEADER_T *mmal_queue_get_core(MMAL_QUEUE_T *queue)
{
   MMAL_BUFFER_HEADER_T * buffer;

   vcos_mutex_lock(&queue->lock);
   mmal_queue_sanity_check(queue, NULL);
   buffer = queue->first;
   vcos_assert(buffer != NULL);

   queue->first = buffer->next;
   if(!queue->first) queue->last = &queue->first;

   queue->length--;
   vcos_mutex_unlock(&queue->lock);

   return buffer;
}
示例#30
0
static MMAL_VC_PAYLOAD_ELEM_T *mmal_vc_payload_list_get()
{
   MMAL_VC_PAYLOAD_ELEM_T *elem = 0;
   unsigned int i;

   vcos_mutex_lock(&mmal_vc_payload_list.lock);
   for (i = 0; i < MMAL_VC_PAYLOAD_ELEM_MAX; i++)
   {
      if (mmal_vc_payload_list.list[i].in_use)
         continue;
      elem = &mmal_vc_payload_list.list[i];
      elem->in_use = 1;
      break;
   }
   vcos_mutex_unlock(&mmal_vc_payload_list.lock);

   return elem;
}