static int simple_pingpong(void)
{
   static VCOS_THREAD_T server, clients[N_CLIENTS];
   unsigned long sent, received = 0;
   void *psent = &sent;
   int i;
   VCOS_STATUS_T st;
   VCOS_MSG_ENDPOINT_T self;

   st = vcos_msgq_endpoint_create(&self,"test");

   st = vcos_thread_create(&server, "server", NULL, simple_server, NULL);

   for (i=0; i<N_CLIENTS; i++)
   {
      st = vcos_thread_create(&clients[i], "client", NULL, simple_client, NULL);
   }

   // wait for the clients to quit
   for (i=0; i<N_CLIENTS; i++)
   {
      unsigned long rx;
      void *prx = &rx;
      vcos_thread_join(&clients[i],prx);
      received += rx;
   }

   // tell the server to quit
   {
      VCOS_MSG_T quit;
      VCOS_MSGQUEUE_T *serverq = vcos_msgq_find("server");

      vcos_assert(serverq != NULL);

      vcos_log("client: sending quit");
      vcos_msg_sendwait(serverq, VCOS_MSG_N_QUIT, &quit);
      vcos_thread_join(&server,psent);
   }

   vcos_msgq_endpoint_delete(&self);

   if (sent == received)
      return 1;
   else
   {
      vcos_log("bad: sent %d, received %d", sent, received);
      return 0;
   }
}
Ejemplo n.º 2
0
		void Start(CThreadProc pThreadProc, T* pInstance, const char* pThreadName = "")
		{
			m_pThreadProc = pThreadProc;
			m_pInstance = pInstance;
			CHECK_VCOS(vcos_thread_create(&m_Thread, pThreadName, NULL, static_cast<VCOS_THREAD_ENTRY_FN_T>(&CThreadT::ThreadProc), this), "failed to create thread");
			CHECK_VCOS(vcos_event_wait(&m_InitializedEvent), "failed to wait for the thread to start");
		}
Ejemplo n.º 3
0
VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread,
                                                            const char *name,
                                                            void *(*entry)(void *arg),
                                                            void *arg,
                                                            void *stack,
                                                            VCOS_UNSIGNED stacksz,
                                                            VCOS_UNSIGNED priaff,
                                                            VCOS_UNSIGNED timeslice,
                                                            VCOS_UNSIGNED autostart)
{
   VCOS_THREAD_ATTR_T attrs;
   vcos_thread_attr_init(&attrs);
   vcos_thread_attr_setstacksize(&attrs, stacksz);
   vcos_thread_attr_setpriority(&attrs, priaff & ~_VCOS_AFFINITY_MASK);
   vcos_thread_attr_setaffinity(&attrs, priaff & _VCOS_AFFINITY_MASK);
   (void)timeslice;
   (void)autostart;

   if (VCOS_CAN_SET_STACK_ADDR)
   {
      vcos_thread_attr_setstack(&attrs, stack, stacksz);
   }

   return vcos_thread_create(thread, name, &attrs, entry, arg);
}
VCOS_STATUS_T vcos_thread_create_classic(VCOS_THREAD_T *thread,
                                         const char *name,
                                         void *(*entry)(void* arg),
                                         void *arg,
                                         void *stack,
                                         VCOS_UNSIGNED stacksz,
                                         VCOS_UNSIGNED priaff,
                                         VCOS_UNSIGNED timeslice,
                                         VCOS_UNSIGNED autostart)
{
   VCOS_STATUS_T status;
   VCOS_THREAD_ATTR_T attrs;
   VCOS_UNSIGNED priority = priaff & ~VCOS_AFFINITY_MASK;
   VCOS_UNSIGNED affinity = priaff & VCOS_AFFINITY_MASK;

   vcos_thread_attr_init(&attrs);
#if VCOS_CAN_SET_STACK_ADDR
   vcos_thread_attr_setstack(&attrs, stack, stacksz);
#else
   vcos_assert(stack == 0);
#endif

   vcos_assert((autostart == VCOS_START) || (autostart == VCOS_NO_START));

   vcos_thread_attr_setpriority(&attrs, priority);
   vcos_thread_attr_setaffinity(&attrs, affinity);
   vcos_thread_attr_settimeslice(&attrs, timeslice);
   vcos_thread_attr_setautostart(&attrs, autostart);

   status = vcos_thread_create(thread, name, &attrs, entry, arg);

   return status;
}
static int32_t guard_init(GUARD_T *guard)
{
   memset(guard, 0, sizeof(GUARD_T));

   if(vcos_semaphore_create(&guard->go, "go", 0) != VCOS_SUCCESS)
      return -1;

   if(vcos_semaphore_create(&guard->done, "done", 0) != VCOS_SUCCESS)
   {
      vcos_semaphore_delete(&guard->go);
      return -1;
   }

   if(vcos_event_flags_create(&guard->event, "event") != VCOS_SUCCESS)
   {
      vcos_semaphore_delete(&guard->go);
      vcos_semaphore_delete(&guard->done);
      return -1;
   }
   
   if (vcos_thread_create(&guard->thread, "guard", NULL, guard_func, guard) != VCOS_SUCCESS)
   {
      vcos_event_flags_delete(&guard->event);
      vcos_semaphore_delete(&guard->go);
      vcos_semaphore_delete(&guard->done);
      return -1;
   }

   return 0;
}
Ejemplo n.º 6
0
static int32_t waiter_init(WAITER_T *waiter, VCOS_EVENT_FLAGS_T *event, int id)
{
   memset(waiter, 0, sizeof(WAITER_T));
   waiter->id = id;

   if(vcos_semaphore_create(&waiter->go, "go", 0) != VCOS_SUCCESS)
      return -1;

   if(vcos_semaphore_create(&waiter->done, "done", 0) != VCOS_SUCCESS)
   {
      vcos_semaphore_delete(&waiter->go);
      return -1;
   }

   waiter->event = event;

   if (vcos_thread_create(&waiter->thread, "waiter", NULL, waiter_func, waiter) != VCOS_SUCCESS)
   {
      vcos_semaphore_delete(&waiter->go);
      vcos_semaphore_delete(&waiter->done);
      return -1;
   }

   return 0;
}
Ejemplo n.º 7
0
/***********************************************************
 * Name: os_thread_begin
 *
 * Arguments:  VCOS_THREAD_T *thread
 *             OS_THREAD_FUNC_T func
 *             int stack
 *             void *data
 *             const char *name
 *
 * Description: Routine to create and start a thread or task for VCHIQ
 * Thread function has different arguments (void*) to os_thread_start (int,void*).
 * 
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
void os_thread_begin(VCOS_THREAD_T *thread, void (*func)(void*), int stack, void *data, const char *name) 
{
   VCOS_THREAD_ATTR_T attrs;
   VCOS_STATUS_T status;
   vcos_thread_attr_init(&attrs);
   vcos_thread_attr_setstacksize(&attrs, stack);
   vcos_thread_attr_setpriority(&attrs, 5); /* FIXME: should not be hardcoded */
   vcos_thread_attr_settimeslice(&attrs, 20); /* FIXME: should not be hardcoded */

   status = vcos_thread_create(thread, name, &attrs, (VCOS_THREAD_ENTRY_FN_T)func, data);
   vcos_assert(status == VCOS_SUCCESS);
}
Ejemplo n.º 8
0
/**
 * Starts the worker / GL renderer thread.
 * @pre raspitex_init was successful
 * @pre raspitex_configure_preview_port was successful
 * @param state Pointer to the GL preview state.
 * @return Zero on success, otherwise, -1 is returned
 * */
int raspitex_start(RASPITEX_STATE *state)
{
    VCOS_STATUS_T status;

    vcos_log_trace("%s", VCOS_FUNCTION);
    status = vcos_thread_create(&state->preview_thread, "preview-worker",
                                NULL, preview_worker, state);

    if (status != VCOS_SUCCESS)
        vcos_log_error("%s: Failed to start worker thread %d",
                       VCOS_FUNCTION, status);

    return (status == VCOS_SUCCESS ? 0 : -1);
}
Ejemplo n.º 9
0
int32_t os_thread_start( VCOS_THREAD_T *thread, OS_THREAD_FUNC_T func, void *arg, uint32_t stack_size, const char *name ) 
{
   VCOS_STATUS_T st;
   VCOS_THREAD_ATTR_T attrs;
   vcos_thread_attr_init(&attrs);
   vcos_thread_attr_setstacksize(&attrs, stack_size);
   vcos_thread_attr_settimeslice(&attrs, 1);

   /* Os_threads assume (argc, argv) as arguments, with argc=0. The default vcos thread
    * just passes in argv as the first argument. Use this to change it. This kludge
    * needs to be removed once os_thread_start() is completely withdrawn.
    */
   _vcos_thread_attr_setlegacyapi(&attrs,1);
   st = vcos_thread_create(thread, name, &attrs, (VCOS_THREAD_ENTRY_FN_T)func, arg);
   return (st==VCOS_SUCCESS?0:-1);
}
Ejemplo n.º 10
0
void vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_CHANNEL_T *local, VCHIQ_CHANNEL_T *remote)
{
   VCOS_THREAD_ATTR_T attrs;
   char threadname[8];
   static int id = 0;

   vcos_assert(is_pow2(VCHIQ_CHANNEL_SIZE));

   vcos_assert(is_pow2(VCHIQ_NUM_CURRENT_BULKS));
   vcos_assert(is_pow2(VCHIQ_NUM_SERVICE_BULKS));

   vcos_assert(sizeof(VCHIQ_HEADER_T) == 8);    /* we require this for consistency between endpoints */

   memset(state, 0, sizeof(VCHIQ_STATE_T));
   state->id = id++;

   /*
      initialize events and mutex
   */

   vcos_event_create(&state->connect, "vchiq");
   vcos_mutex_create(&state->mutex, "vchiq");

   /*
      initialize channel pointers
   */

   state->local  = local;
   state->remote = remote;
   vchiq_init_channel(local);

   /*
      bring up slot handler thread
   */

   vcos_thread_attr_init(&attrs);
   vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK);
   vcos_thread_attr_setpriority(&attrs, 5); /* FIXME: should not be hardcoded */
   vcos_thread_attr_settimeslice(&attrs, 20); /* FIXME: should not be hardcoded */
   strcpy(threadname, "VCHIQ-0");
   threadname[6] += state->id % 10;
   vcos_thread_create(&state->slot_handler_thread, threadname,
                      &attrs, slot_handler_func, state);

   /* Indicate readiness to the other side */
   local->initialised = 1;
}
Ejemplo n.º 11
0
/* Start SVP. Enables MMAL connection + creates worker thread. */
int svp_start(SVP_T *svp)
{
   MMAL_STATUS_T st;
   VCOS_STATUS_T vst;

   /* Ensure SVP is stopped first */
   svp_stop(svp);

   /* Reset the worker thread stop status, before enabling ports that might trigger a stop */
   svp_reset_stop(svp);

   if (svp->connection)
   {
      /* Enable reader->decoder connection */
      st = mmal_connection_enable(svp->connection);
      CHECK_STATUS(st, "Failed to create connection");
   }

   /* Enable video output port */
   st = svp_port_enable(svp, svp->video_output, svp_bh_output_cb);
   CHECK_STATUS(st, "Failed to enable output port");

   /* Reset stats */
   svp->stats.video_frame_count = 0;

   /* Create worker thread */
   vst = vcos_thread_create(&svp->thread, "svp-worker", NULL, svp_worker, svp);
   CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create connection");

   svp->created |= SVP_CREATED_THREAD;

   /* Set timer */
   if (svp->camera)
   {
      unsigned ms = svp->opts.duration_ms;
      vcos_timer_set(&svp->timer, ((ms == 0) ? SVP_CAMERA_DURATION_MS : ms));
   }

   /* Start watchdog timer */
   vcos_timer_set(&svp->wd_timer, SVP_WATCHDOG_TIMEOUT_MS);

   return 0;

error:
   return -1;
}
bool khrn_worker_init(void)
{
#ifndef KHRN_WORKER_USE_LLAT
   VCOS_THREAD_ATTR_T attr;
#endif
   vcos_assert(!inited);

   khrn_worker_enter_pos = 0;
   khrn_worker_exit_pos_0 = 0;
   khrn_worker_exit_pos_1 = 0;

   khrn_worker_msg.post = msgs;
   khrn_worker_msg.done_it = msgs;
   khrn_worker_msg.cleanup = msgs;

#ifdef KHRN_WORKER_USE_LLAT
   llat_i = khrn_llat_register(khrn_worker_llat_callback);
   vcos_assert(llat_i != -1);
#else
   if (vcos_event_create(&event, "khrn_worker_event") != VCOS_SUCCESS) {
      return false;
   }

   exit_thread = false;

   vcos_thread_attr_init(&attr);
   vcos_thread_attr_setpriority(&attr, THREAD_PRIORITY);
#if !defined(V3D_LEAN)
   switch (vcos_thread_get_affinity(vcos_thread_current())) {
   case VCOS_AFFINITY_CPU0: vcos_thread_attr_setaffinity(&attr, VCOS_AFFINITY_CPU1); break;
   case VCOS_AFFINITY_CPU1: vcos_thread_attr_setaffinity(&attr, VCOS_AFFINITY_CPU0); break;
   }
   vcos_thread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
#endif /* V3D_LEAN */
   if (vcos_thread_create(&thread, "khrn_worker_thread", &attr, khrn_worker_main, NULL) != VCOS_SUCCESS) {
      vcos_event_delete(&event);
      return false;
   }
#endif

   inited = true;

   return true;
}
Ejemplo n.º 13
0
void vc_vchi_dispmanx_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) {
   VCOS_STATUS_T status;
   int32_t success;
   uint32_t i;

   // record the number of connections
   memset( &dispmanx_client, 0, sizeof(DISPMANX_SERVICE_T) );
   dispmanx_client.num_connections = num_connections;

   status = vcos_mutex_create(&dispmanx_client.lock, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   status = vcos_event_create(&dispmanx_message_available_event, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   status = vcos_event_create(&dispmanx_notify_available_event, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   dispmanx_client.initialised = 1;

   for (i=0; i<dispmanx_client.num_connections; i++) {

      VCOS_THREAD_ATTR_T attrs;

      // Create a 'Client' service on the each of the connections
      SERVICE_CREATION_T dispmanx_parameters = { DISPMANX_CLIENT_NAME,     // 4cc service code
                                                 connections[i],           // passed in fn ptrs
                                                 0,                        // tx fifo size (unused)
                                                 0,                        // tx fifo size (unused)
                                                 &dispmanx_client_callback, // service callback
                                                 &dispmanx_message_available_event,  // callback parameter
                                                 VC_FALSE,                  // want_unaligned_bulk_rx
                                                 VC_FALSE,                  // want_unaligned_bulk_tx
                                                 VC_FALSE,                  // want_crc
                                                 };

      SERVICE_CREATION_T dispmanx_parameters2 = { DISPMANX_NOTIFY_NAME,   // 4cc service code
                                                  connections[i],           // passed in fn ptrs
                                                  0,                        // tx fifo size (unused)
                                                  0,                        // tx fifo size (unused)
                                                  &dispmanx_notify_callback, // service callback
                                                  &dispmanx_notify_available_event,  // callback parameter
                                                  VC_FALSE,                  // want_unaligned_bulk_rx
                                                  VC_FALSE,                  // want_unaligned_bulk_tx
                                                  VC_FALSE,                  // want_crc
                                                   };

      success = vchi_service_open( initialise_instance, &dispmanx_parameters, &dispmanx_client.client_handle[i] );
      vcos_assert( success == 0 );

      // Create the async service of dispman to handle update callback

      success = vchi_service_open( initialise_instance, &dispmanx_parameters2, &dispmanx_client.notify_handle[i] );
      vcos_assert( success == 0 );

      //Create the notifier task
      vcos_thread_attr_init(&attrs);
      vcos_thread_attr_setstacksize(&attrs, 2048);
      vcos_thread_attr_settimeslice(&attrs, 1);

      status = vcos_thread_create(&dispmanx_notify_task, "HDispmanx Notify", &attrs, dispmanx_notify_func, NULL);
      vcos_assert(status == VCOS_SUCCESS);

      // release services until they're actually used
      vchi_service_release(dispmanx_client.client_handle[i]);
      vchi_service_release(dispmanx_client.notify_handle[i]);
   }
}
Ejemplo n.º 14
0
int main(int argc, const char **argv)
{
   VCOS_THREAD_ATTR_T attrs;
   int i;

   vcos_init();
   signal(SIGINT, test_signal_handler);

   /* coverity[tainted_data] Ignore unnecessary warning about an attacker
    * being able to pass an arbitrarily long "-vvvvv..." argument */
   if (test_parse_cmdline(argc, argv))
      return -1;

   if (verbosity--)
   {
      static char value[512];
      const char *levels[] = {"warn", "info", "trace"};
      char *env = getenv("VC_LOGLEVEL");
      if (verbosity >= MMAL_COUNTOF(levels)) verbosity = MMAL_COUNTOF(levels) - 1;
      snprintf(value, sizeof(value)-1, "mmalplay:%s,mmal:%s,%s",
               levels[verbosity], levels[verbosity], env ? env : "");
#ifdef WIN32
      _putenv("VC_LOGLEVEL", value, 1);
#else
      setenv("VC_LOGLEVEL", value, 1);
#endif
   }

   vcos_log_register("mmalplay", VCOS_LOG_CATEGORY);
   LOG_INFO("MMAL Video Playback Test App");

   vcos_thread_attr_init(&attrs);
   for (i = 0; i < play_info_count; i++)
   {
      const char *uri = play_info[i].uri;

      memcpy(play_info[i].name, THREAD_PREFIX, sizeof(THREAD_PREFIX));
      if (strlen(uri) >= URI_FOR_THREAD_NAME_MAX)
         uri += strlen(uri) - URI_FOR_THREAD_NAME_MAX;
      strncat(play_info[i].name, uri, URI_FOR_THREAD_NAME_MAX);

      vcos_mutex_create(&play_info[i].lock, "mmalplay");
      play_info[i].options.render_layer = i;

      if (vcos_thread_create(&play_info[i].thread, play_info[i].name, &attrs, mmal_playback, &play_info[i]) != VCOS_SUCCESS)
      {
         LOG_ERROR("Thread creation failure for URI %s", play_info[i].uri);
         return -2;
      }
   }

   if (sleepy_time != 0)
   {
#ifdef WIN32
      Sleep(sleepy_time);
#else
      sleep(sleepy_time);
#endif
      for (i = 0; i < play_info_count; i++)
      {
         vcos_mutex_lock(&play_info[i].lock);
         if (play_info[i].ctx)
            mmalplay_stop(play_info[i].ctx);
         vcos_mutex_unlock(&play_info[i].lock);
      }
   }

   LOG_TRACE("Waiting for threads to terminate");
   for (i = 0; i < play_info_count; i++)
   {
      vcos_thread_join(&play_info[i].thread, NULL);
      LOG_TRACE("Joined thread %d (%i)", i, play_info[i].status);
   }

   LOG_TRACE("Completed");

   /* Check for errors */
   for (i = 0; i < play_info_count; i++)
   {
      if (!play_info[i].status)
         continue;

      LOG_ERROR("Playback of %s failed (%i, %s)", play_info[i].uri,
                play_info[i].status,
                mmal_status_to_string(play_info[i].status));
      fprintf(stderr, "playback of %s failed (%i, %s)\n", play_info[i].uri,
              play_info[i].status,
              mmal_status_to_string(play_info[i].status));
      return play_info[i].status;
   }

   return 0;
}