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 = ℞ 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; } }
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"); }
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; }
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; }
/*********************************************************** * 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); }
/** * 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); }
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); }
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; }
/* 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; }
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]); } }
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; }