/* If sequential consistency mode is enabled, this function blocks until the * handle is available in the requested access mode. */ int _starpu_data_wait_until_available(starpu_data_handle handle, starpu_access_mode mode) { /* If sequential consistency is enabled, wait until data is available */ PTHREAD_MUTEX_LOCK(&handle->sequential_consistency_mutex); int sequential_consistency = handle->sequential_consistency; if (sequential_consistency) { struct starpu_task *sync_task; sync_task = starpu_task_create(); sync_task->destroy = 1; /* It is not really a RW access, but we want to make sure that * all previous accesses are done */ _starpu_detect_implicit_data_deps_with_handle(sync_task, sync_task, handle, mode); PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex); /* TODO detect if this is superflous */ starpu_event event; int ret = starpu_task_submit(sync_task, &event); STARPU_ASSERT(!ret); starpu_event_wait(event); starpu_event_release(event); } else { PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex); } return 0; }
/** Close the log file. Really just return it to the pool. * * When multithreaded, the FD is locked via a mutex. This way we're * sure that no other thread is writing to the file. This function * will unlock the mutex, so that other threads can write to the file. * * @param lf The logfile context returned from fr_logfile_init() * @param fd the FD to close (i.e. return to the pool) * @return 0 on success, or -1 on error */ int fr_logfile_close(fr_logfile_t *lf, int fd) { int i; for (i = 0; i < lf->max_entries; i++) { if (!lf->entries[i].filename) continue; /* * Unlock the bytes that we had previously locked. */ if (lf->entries[i].dup == fd) { (void) rad_unlockfd(lf->entries[i].dup, 0); close(lf->entries[i].dup); /* releases the fcntl lock */ lf->entries[i].dup = -1; PTHREAD_MUTEX_UNLOCK(&(lf->mutex)); return 0; } } PTHREAD_MUTEX_UNLOCK(&(lf->mutex)); fr_strerror_printf("Attempt to unlock file which does not exist"); return -1; }
int proxy_tls_send(rad_listen_t *listener, REQUEST *request) { int rcode; listen_socket_t *sock = listener->data; /* * Normal proxying calls us with the data already * encoded. The "ping home server" code does not. So, * if there's no packet, encode it here. */ if (!request->proxy->data) { request->proxy_listener->encode(request->proxy_listener, request); } DEBUG3("Proxy is writing %u bytes to SSL", (unsigned int) request->proxy->data_len); PTHREAD_MUTEX_LOCK(&sock->mutex); while ((rcode = SSL_write(sock->ssn->ssl, request->proxy->data, request->proxy->data_len)) < 0) { int err; while ((err = ERR_get_error())) { DEBUG("proxy SSL_write says %s", ERR_error_string(err, NULL)); } PTHREAD_MUTEX_UNLOCK(&sock->mutex); tls_socket_close(listener); return 0; } PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 1; }
static void _handle_pending_node_data_requests(uint32_t src_node, unsigned force) { // _STARPU_DEBUG("_starpu_handle_pending_node_data_requests ...\n"); PTHREAD_MUTEX_LOCK(&data_requests_pending_list_mutex[src_node]); /* for all entries of the list */ starpu_data_request_list_t local_list = data_requests_pending[src_node]; data_requests_pending[src_node] = starpu_data_request_list_new(); PTHREAD_MUTEX_UNLOCK(&data_requests_pending_list_mutex[src_node]); while (!starpu_data_request_list_empty(local_list)) { starpu_data_request_t r; r = starpu_data_request_list_pop_back(local_list); if (r->src_handle != r->dst_handle) { _starpu_spin_lock(&r->src_handle->header_lock); _starpu_spin_lock(&r->dst_handle->header_lock); } else _starpu_spin_lock(&r->src_handle->header_lock); _starpu_spin_lock(&r->lock); /* wait until the transfer is terminated */ if (force) { _starpu_driver_wait_request_completion(r, src_node); starpu_handle_data_request_completion(r); } else { if (_starpu_driver_test_request_completion(r, src_node)) { starpu_handle_data_request_completion(r); } else { _starpu_spin_unlock(&r->lock); if (r->src_handle != r->dst_handle) { _starpu_spin_unlock(&r->src_handle->header_lock); _starpu_spin_unlock(&r->dst_handle->header_lock); } else _starpu_spin_unlock(&r->src_handle->header_lock); /* wake the requesting worker up */ PTHREAD_MUTEX_LOCK(&data_requests_pending_list_mutex[src_node]); starpu_data_request_list_push_front(data_requests_pending[src_node], r); PTHREAD_MUTEX_UNLOCK(&data_requests_pending_list_mutex[src_node]); } } } starpu_data_request_list_delete(local_list); }
void *_starpu_gordon_worker(void *arg) { struct starpu_worker_set_s *gordon_set_arg = arg; _starpu_bind_thread_on_cpu(gordon_set_arg->config, gordon_set_arg->workers[0].bindid); /* TODO set_local_memory_node per SPU */ gordon_init(gordon_set_arg->nworkers); /* NB: On SPUs, the worker_key is set to NULL since there is no point * in associating the PPU thread with a specific SPU (worker) while * it's handling multiple processing units. */ _starpu_set_local_worker_key(NULL); /* TODO set workers' name field */ unsigned spu; for (spu = 0; spu < gordon_set_arg->nworkers; spu++) { struct starpu_worker_s *worker = &gordon_set_arg->workers[spu]; snprintf(worker->name, 32, "SPU %d", worker->id); } /* * To take advantage of PPE being hyperthreaded, we should have 2 threads * for the gordon driver : one injects works, the other makes sure that * gordon is progressing (and performs the callbacks). */ /* launch the progression thread */ PTHREAD_MUTEX_INIT(&progress_mutex, NULL); PTHREAD_COND_INIT(&progress_cond, NULL); pthread_create(&progress_thread, NULL, gordon_worker_progress, gordon_set_arg); /* wait for the progression thread to be ready */ PTHREAD_MUTEX_LOCK(&progress_mutex); while (!progress_thread_is_inited) PTHREAD_COND_WAIT(&progress_cond, &progress_mutex); PTHREAD_MUTEX_UNLOCK(&progress_mutex); _STARPU_DEBUG("progress thread is running ... \n"); /* tell the core that gordon is ready */ PTHREAD_MUTEX_LOCK(&gordon_set_arg->mutex); gordon_set_arg->set_is_initialized = 1; PTHREAD_COND_SIGNAL(&gordon_set_arg->ready_cond); PTHREAD_MUTEX_UNLOCK(&gordon_set_arg->mutex); gordon_worker_inject(gordon_set_arg); _STARPU_DEBUG("gordon deinit...\n"); gordon_deinit(); _STARPU_DEBUG("gordon was deinited\n"); pthread_exit((void *)0x42); }
static int ddc_receive_frame(void* data, int streamId, unsigned char* buffer, unsigned int bufferSize) { DVDecodeStreamConnect* connect = (DVDecodeStreamConnect*)data; int status; int result = 1; if (connect->sourceStreamId != streamId) { ml_log_error("Received frame for unknown source stream %d in copy connect\n", streamId); return 0; } /* signal to ddc_sync at later time that we have received a frame to decode and send */ connect->frameWasReceived = 1; if (!connect->useWorkerThread) { result = decode_and_send(connect); } else { /* check that the worker isn't busy */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); if (connect->workerIsBusy) { ml_log_error("DV connect worker thread is still busy, and therefore cannot receive a new frame\n"); result = 0; } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); if (result != 1) { return result; } /* signal worker that a new frame is ready */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); connect->frameIsReady = 1; status = pthread_cond_signal(&connect->frameIsReadyCond); if (status != 0) { ml_log_error("DV connect worker thread failed to send frame is ready condition signal\n"); result = 0; } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); } return result; }
/* The data must be released by calling starpu_data_release later on */ int starpu_data_acquire_cb(starpu_data_handle handle, starpu_access_mode mode, void (*callback)(void *), void *arg) { STARPU_ASSERT(handle); struct user_interaction_wrapper *wrapper = malloc(sizeof(struct user_interaction_wrapper)); STARPU_ASSERT(wrapper); wrapper->handle = handle; wrapper->mode = mode; wrapper->callback = callback; wrapper->callback_arg = arg; PTHREAD_COND_INIT(&wrapper->cond, NULL); PTHREAD_MUTEX_INIT(&wrapper->lock, NULL); wrapper->finished = 0; //TODO: instead of having the is_prefetch argument, _starpu_fetch_data shoud consider two flags: async and detached _starpu_spin_lock(&handle->header_lock); handle->per_node[0].refcnt++; _starpu_spin_unlock(&handle->header_lock); PTHREAD_MUTEX_LOCK(&handle->sequential_consistency_mutex); int sequential_consistency = handle->sequential_consistency; if (sequential_consistency) { wrapper->pre_sync_task = starpu_task_create(); wrapper->pre_sync_task->callback_func = starpu_data_acquire_cb_pre_sync_callback; wrapper->pre_sync_task->callback_arg = wrapper; wrapper->post_sync_task = starpu_task_create(); #ifdef STARPU_USE_FXT starpu_job_t job = _starpu_get_job_associated_to_task(wrapper->pre_sync_task); job->model_name = "acquire_cb_pre"; job = _starpu_get_job_associated_to_task(wrapper->post_sync_task); job->model_name = "acquire_cb_post"; #endif _starpu_detect_implicit_data_deps_with_handle(wrapper->pre_sync_task, wrapper->post_sync_task, handle, mode); PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex); /* TODO detect if this is superflous */ int ret = starpu_task_submit(wrapper->pre_sync_task, NULL); STARPU_ASSERT(!ret); } else { PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex); starpu_data_acquire_cb_pre_sync_callback(wrapper); } return 0; }
/* vpe_hardware_open_subdev: * * opens the vpe subdev and updates instance info. * updates the hardware status. * currently only one vpe subdevice is supported. **/ int32_t vpe_hardware_open_subdev(vpe_hardware_t *vpehw) { int fd, rc=0; char dev_name[SUBDEV_NAME_SIZE_MAX]; if(!vpehw) { CDBG_ERROR("%s:%d: failed\n", __func__, __LINE__); return -EINVAL; } /* make sure all code-paths unlock this mutex */ PTHREAD_MUTEX_LOCK(&(vpehw->mutex)); if (vpehw->subdev_opened == TRUE) { CDBG_HIGH("%s:%d: subdev already open\n", __func__, __LINE__); rc = -EFAULT; goto error_mutex; } snprintf(dev_name, sizeof(dev_name), "/dev/v4l-subdev%d", vpehw->subdev_ids[0]); fd = open(dev_name, O_RDWR | O_NONBLOCK); if (fd < 0) { CDBG_ERROR("%s:%d: error: cannot open vpe subdev: %s\n", __func__, __LINE__, dev_name); rc = -EIO; goto error_mutex; } vpehw->subdev_fd = fd; vpehw->subdev_opened = TRUE; /* get the instance info */ struct msm_camera_v4l2_ioctl_t v4l2_ioctl; struct msm_vpe_frame_info_t inst_info; memset(&inst_info, 0x00, sizeof(struct msm_vpe_frame_info_t)); v4l2_ioctl.ioctl_ptr = &inst_info; v4l2_ioctl.len = sizeof(inst_info); rc = ioctl(vpehw->subdev_fd, VIDIOC_MSM_VPE_GET_INST_INFO, &v4l2_ioctl); if (rc < 0) { CDBG_ERROR("%s:%d: v4l2 ioctl() failed, rc=%d\n", __func__, __LINE__, rc); rc = -EIO; goto error_open; } vpehw->inst_id = inst_info.inst_id; /* update hw state */ vpehw->status = VPE_HW_STATUS_READY; CDBG("%s:%d, vpe subdev opened, subdev_fd=%d, status=%d", __func__, __LINE__, vpehw->subdev_fd, vpehw->status); PTHREAD_MUTEX_UNLOCK(&(vpehw->mutex)); return 0; error_open: close(fd); error_mutex: PTHREAD_MUTEX_UNLOCK(&(vpehw->mutex)); return rc; }
int proxy_tls_send(rad_listen_t *listener, REQUEST *request) { int rcode; listen_socket_t *sock = listener->data; VERIFY_REQUEST(request); if ((listener->status != RAD_LISTEN_STATUS_INIT) && (listener->status != RAD_LISTEN_STATUS_KNOWN)) return 0; /* * Normal proxying calls us with the data already * encoded. The "ping home server" code does not. So, * if there's no packet, encode it here. */ if (!request->proxy->data) { request->proxy_listener->encode(request->proxy_listener, request); } DEBUG3("Proxy is writing %u bytes to SSL", (unsigned int) request->proxy->data_len); PTHREAD_MUTEX_LOCK(&sock->mutex); rcode = SSL_write(sock->tls_session->ssl, request->proxy->data, request->proxy->data_len); if (rcode < 0) { int err; err = ERR_get_error(); switch (err) { case SSL_ERROR_NONE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: break; /* let someone else retry */ default: DEBUG("proxy SSL_write says %s", ERR_error_string(err, NULL)); DEBUG("Closing TLS socket to home server"); tls_socket_close(listener); PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; } } PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 1; }
/* * walk the entire tree. The compare function CANNOT modify * the tree. * * The compare function should return 0 to continue walking. * Any other value stops the walk, and is returned. */ int rbtree_walk(rbtree_t *tree, rb_order_t order, rb_walker_t compare, void *context) { int rcode; if (tree->root == NIL) return 0; PTHREAD_MUTEX_LOCK(tree); switch (order) { case RBTREE_PRE_ORDER: rcode = walk_node_pre_order(tree->root, compare, context); break; case RBTREE_IN_ORDER: rcode = walk_node_in_order(tree->root, compare, context); break; case RBTREE_POST_ORDER: rcode = walk_node_post_order(tree->root, compare, context); break; case RBTREE_DELETE_ORDER: rcode = walk_delete_order(tree, compare, context); break; default: rcode = -1; break; } PTHREAD_MUTEX_UNLOCK(tree); return rcode; }
starpu_job_t _starpu_stack_pop_task(struct starpu_stack_jobq_s *stack_queue, pthread_mutex_t *sched_mutex) { starpu_job_t j = NULL; if (stack_queue->njobs == 0) return NULL; if (stack_queue->njobs > 0) { /* there is a task */ j = starpu_job_list_pop_back(stack_queue->jobq); STARPU_ASSERT(j); stack_queue->njobs--; STARPU_TRACE_JOB_POP(j, 0); /* we are sure that we got it now, so at worst, some people thought * there remained some work and will soon discover it is not true */ PTHREAD_MUTEX_LOCK(sched_mutex); total_number_of_jobs--; PTHREAD_MUTEX_UNLOCK(sched_mutex); } return j; }
/** * @param * A pointer to a Timer structure to cancel and free. */ void timerFree(void *_timer) { Timer *timer = (Timer *) _timer; if (timer != NULL) { timer->task = NULL; CLOCK_SUB(&timer->period, &timer->period); #ifdef __unix__ PTHREAD_MUTEX_LOCK(&timer->mutex); # if defined(HAVE_PTHREAD_COND_TIMEDWAIT) (void) pthread_cond_signal(&timer->cv); # else (void) pthread_cancel(timer->thread); # endif PTHREAD_MUTEX_UNLOCK(&timer->mutex); #endif #if defined(__WIN32__) || defined(__CYGWIN__) SetEvent(timer->cancel_event); #endif (void) pthread_join(timer->thread, NULL); #if defined(HAVE_PTHREAD_COND_TIMEDWAIT) (void) pthread_cond_destroy(&timer->cv); (void) pthreadMutexDestroy(&timer->mutex); #endif #if defined(__WIN32__) || defined(__CYGWIN__) CloseHandle(timer->cancel_event); #endif if (timer->free_data != NULL) (*timer->free_data)(timer->data); free(timer); } }
void *gordon_worker_progress(void *arg) { _STARPU_DEBUG("gordon_worker_progress\n"); /* fix the thread on the correct cpu */ struct starpu_worker_set_s *gordon_set_arg = arg; unsigned prog_thread_bind_id = (gordon_set_arg->workers[0].bindid + 1)%(gordon_set_arg->config->nhwcores); _starpu_bind_thread_on_cpu(gordon_set_arg->config, prog_thread_bind_id); PTHREAD_MUTEX_LOCK(&progress_mutex); progress_thread_is_inited = 1; PTHREAD_COND_SIGNAL(&progress_cond); PTHREAD_MUTEX_UNLOCK(&progress_mutex); while (1) { /* the Gordon runtime needs to make sure that we poll it * so that we handle jobs that are done */ /* wait for one task termination */ int ret = gordon_wait(0); if (ret) { /* possibly wake the thread that injects work */ starpu_wake_all_blocked_workers(); } } return NULL; }
/** Inserts a backtrace marker into the provided context * * Allows for maximum laziness and will initialise a circular buffer if one has not already been created. * * Code augmentation should look something like: @verbatim // Create a static cbuffer pointer, the first call to backtrace_attach will initialise it static fr_cbuff *my_obj_bt; my_obj_t *alloc_my_obj(TALLOC_CTX *ctx) { my_obj_t *this; this = talloc(ctx, my_obj_t); // Attach backtrace marker to object backtrace_attach(&my_obj_bt, this); return this; } @endverbatim * * Then, later when a double free occurs: @verbatim (gdb) call backtrace_print(&my_obj_bt, <pointer to double freed memory>) @endverbatim * * which should print a limited backtrace to stderr. Note, this backtrace will not include any argument * values, but should at least show the code path taken. * * @param cbuff this should be a pointer to a static *fr_cbuff. * @param obj we want to generate a backtrace for. */ fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj) { fr_bt_marker_t *marker; if (*cbuff == NULL) { PTHREAD_MUTEX_LOCK(&fr_debug_init); /* Check again now we hold the mutex - eww*/ if (*cbuff == NULL) { TALLOC_CTX *ctx; ctx = fr_autofree_ctx(); *cbuff = fr_cbuff_alloc(ctx, MAX_BT_CBUFF, true); } PTHREAD_MUTEX_UNLOCK(&fr_debug_init); } marker = talloc(obj, fr_bt_marker_t); if (!marker) { return NULL; } marker->obj = (void *) obj; marker->cbuff = *cbuff; talloc_set_destructor(marker, _fr_do_bt); return marker; }
void x11c_clear(X11Common* x11Common) { x11Common->stopped = 1; join_thread(&x11Common->processEventThreadId, NULL, NULL); PTHREAD_MUTEX_LOCK(&x11Common->eventMutex) /* don't allow events to be processed */ kic_free_keyboard_connect(&x11Common->keyboardConnect); pic_free_progress_bar_connect(&x11Common->progressBarConnect); mic_free_mouse_connect(&x11Common->mouseConnect); if (x11Common->createdWindowInfo) { x11c_close_window(&x11Common->windowInfo); x11Common->createdWindowInfo = 0; } SAFE_FREE(&x11Common->windowName); x11Common->osd = NULL; PTHREAD_MUTEX_UNLOCK(&x11Common->eventMutex) destroy_mutex(&x11Common->eventMutex); memset(x11Common, 0, sizeof(x11Common)); }
void eap_handler_free(rlm_eap_t *inst, eap_handler_t *handler) { if (!handler) return; if (handler->identity) { talloc_free(handler->identity); handler->identity = NULL; } if (handler->prev_eapds) eap_ds_free(&(handler->prev_eapds)); if (handler->eap_ds) eap_ds_free(&(handler->eap_ds)); if ((handler->opaque) && (handler->free_opaque)) { handler->free_opaque(handler->opaque); handler->opaque = NULL; } handler->opaque = NULL; handler->free_opaque = NULL; if (handler->certs) pairfree(&handler->certs); PTHREAD_MUTEX_LOCK(&(inst->handler_mutex)); if (inst->handler_tree) { rbtree_deletebydata(inst->handler_tree, handler); } talloc_free(handler); PTHREAD_MUTEX_UNLOCK(&(inst->handler_mutex)); }
static void http_player_state_txt(struct shttpd_arg* arg) { HTTPAccess* access = (HTTPAccess*)arg->user_data; int i; shttpd_printf(arg, "HTTP/1.1 200 OK\r\n"); shttpd_printf(arg, "Content-type: text/plain\r\n\r\n"); PTHREAD_MUTEX_LOCK(&access->playerStateMutex); shttpd_printf(arg, "length=%"PRId64"\n", access->currentFrameInfo.sourceLength); shttpd_printf(arg, "availableLength=%"PRId64"\n", access->currentFrameInfo.availableSourceLength); shttpd_printf(arg, "position=%"PRId64"\n", access->currentFrameInfo.position); shttpd_printf(arg, "startOffset=%"PRId64"\n", access->currentFrameInfo.startOffset); shttpd_printf(arg, "vtrErrorLevel=%u\n", access->currentFrameInfo.vtrErrorLevel); shttpd_printf(arg, "numMarkSelections=%d\n", access->currentFrameInfo.numMarkSelections); for (i = 0; i < access->currentFrameInfo.numMarkSelections; i++) { shttpd_printf(arg, "markFilter_%d=%u\n", i, access->currentFrameInfo.markTypeMasks[i]); } PTHREAD_MUTEX_UNLOCK(&access->playerStateMutex); arg->flags |= SHTTPD_END_OF_OUTPUT; }
/** Inserts a backtrace marker into the provided context * * Allows for maximum laziness and will initialise a circular buffer if one has not already been created. * * Code augmentation should look something like: @verbatim // Create a static cbuffer pointer, the first call to backtrace_attach will initialise it static fr_cbuff_t *my_obj_bt; my_obj_t *alloc_my_obj(TALLOC_CTX *ctx) { my_obj_t *this; this = talloc(ctx, my_obj_t); // Attach backtrace marker to object backtrace_attach(&my_obj_bt, this); return this; } @endverbatim * * Then, later when a double free occurs: @verbatim (gdb) call backtrace_print(&my_obj_bt, <pointer to double freed memory>) @endverbatim * * which should print a limited backtrace to stderr. Note, this backtrace will not include any argument * values, but should at least show the code path taken. * * @param cbuff this should be a pointer to a static *fr_cbuff. * @param obj we want to generate a backtrace for. */ fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj) { fr_bt_marker_t *marker; if (*cbuff == NULL) { PTHREAD_MUTEX_LOCK(&fr_debug_init); /* Check again now we hold the mutex - eww*/ if (*cbuff == NULL) *cbuff = fr_cbuff_alloc(NULL, MAX_BT_CBUFF, true); PTHREAD_MUTEX_UNLOCK(&fr_debug_init); } marker = talloc(obj, fr_bt_marker_t); if (!marker) { return NULL; } marker->obj = (void *) obj; marker->cbuff = *cbuff; fprintf(stderr, "Backtrace attached to %s %p\n", talloc_get_name(obj), obj); /* * Generate the backtrace for memory allocation */ fr_backtrace_do(marker); talloc_set_destructor(marker, fr_backtrace_do); return marker; }
static void hac_state_change_event(void* data, const MediaPlayerStateEvent* event) { HTTPAccess* access = (HTTPAccess*)data; PTHREAD_MUTEX_LOCK(&access->playerStateMutex); access->currentPlayerState = *event; PTHREAD_MUTEX_UNLOCK(&access->playerStateMutex); }
static void hac_frame_displayed_event(void* data, const FrameInfo* frameInfo) { HTTPAccess* access = (HTTPAccess*)data; PTHREAD_MUTEX_LOCK(&access->playerStateMutex); access->currentFrameInfo = *frameInfo; PTHREAD_MUTEX_UNLOCK(&access->playerStateMutex); }
void _starpu_handle_node_data_requests(uint32_t src_node, unsigned may_alloc) { /* for all entries of the list */ starpu_data_request_t r; /* take all the entries from the request list */ PTHREAD_MUTEX_LOCK(&data_requests_list_mutex[src_node]); starpu_data_request_list_t local_list = data_requests[src_node]; if (starpu_data_request_list_empty(local_list)) { /* there is no request */ PTHREAD_MUTEX_UNLOCK(&data_requests_list_mutex[src_node]); return; } data_requests[src_node] = starpu_data_request_list_new(); PTHREAD_MUTEX_UNLOCK(&data_requests_list_mutex[src_node]); while (!starpu_data_request_list_empty(local_list)) { int res; r = starpu_data_request_list_pop_back(local_list); res = starpu_handle_data_request(r, may_alloc); if (res == ENOMEM) { PTHREAD_MUTEX_LOCK(&data_requests_list_mutex[src_node]); starpu_data_request_list_push_front(data_requests[src_node], r); PTHREAD_MUTEX_UNLOCK(&data_requests_list_mutex[src_node]); } /* wake the requesting worker up */ // if we do not progress .. // pthread_cond_broadcast(&data_requests_list_cond[src_node]); } starpu_data_request_list_delete(local_list); }
/* TODO : accounting to see how much time was spent working for other people ... */ static int starpu_handle_data_request(starpu_data_request_t r, unsigned may_alloc) { if (r->src_handle != r->dst_handle) { _starpu_spin_lock(&r->src_handle->header_lock); _starpu_spin_lock(&r->dst_handle->header_lock); } else _starpu_spin_lock(&r->src_handle->header_lock); _starpu_spin_lock(&r->lock); if (r->mode & STARPU_R) { STARPU_ASSERT(r->src_handle->per_node[r->src_node].allocated); STARPU_ASSERT(r->src_handle->per_node[r->src_node].refcnt); } /* perform the transfer */ /* the header of the data must be locked by the worker that submitted the request */ r->retval = _starpu_driver_copy_data_1_to_1(r->src_handle, r->src_node, r->dst_handle, r->dst_node, !(r->mode & STARPU_R), r, may_alloc); if (r->retval == ENOMEM) { _starpu_spin_unlock(&r->lock); if (r->src_handle != r->dst_handle) { _starpu_spin_unlock(&r->src_handle->header_lock); _starpu_spin_unlock(&r->dst_handle->header_lock); } else _starpu_spin_unlock(&r->src_handle->header_lock); return ENOMEM; } if (r->retval == EAGAIN) { _starpu_spin_unlock(&r->lock); if (r->src_handle != r->dst_handle) { _starpu_spin_unlock(&r->src_handle->header_lock); _starpu_spin_unlock(&r->dst_handle->header_lock); } else _starpu_spin_unlock(&r->src_handle->header_lock); /* the request is pending and we put it in the corresponding queue */ PTHREAD_MUTEX_LOCK(&data_requests_pending_list_mutex[r->handling_node]); starpu_data_request_list_push_front(data_requests_pending[r->handling_node], r); PTHREAD_MUTEX_UNLOCK(&data_requests_pending_list_mutex[r->handling_node]); return EAGAIN; } /* the request has been handled */ starpu_handle_data_request_completion(r); return 0; }
/* * Send a response packet */ int dual_tls_send(rad_listen_t *listener, REQUEST *request) { listen_socket_t *sock = listener->data; rad_assert(request->listener == listener); rad_assert(listener->send == dual_tls_send); /* * Accounting reject's are silently dropped. * * We do it here to avoid polluting the rest of the * code with this knowledge */ if (request->reply->code == 0) return 0; /* * Pack the VPs */ if (rad_encode(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed encoding packet: %s", fr_strerror()); return 0; } /* * Sign the packet. */ if (rad_sign(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed signing packet: %s", fr_strerror()); return 0; } PTHREAD_MUTEX_LOCK(&sock->mutex); /* * Write the packet to the SSL buffers. */ sock->ssn->record_plus(&sock->ssn->clean_in, request->reply->data, request->reply->data_len); /* * Do SSL magic to get encrypted data. */ tls_handshake_send(request, sock->ssn); /* * And finally write the data to the socket. */ if (sock->ssn->dirty_out.used > 0) { dump_hex("WRITE TO SSL", sock->ssn->dirty_out.data, sock->ssn->dirty_out.used); tls_socket_write(listener, request); } PTHREAD_MUTEX_UNLOCK(&sock->mutex); return 0; }
int fr_logfile_unlock(fr_logfile_t *lf, int fd) { int i; for (i = 0; i < lf->max_entries; i++) { if (!lf->entries[i].filename) continue; if (lf->entries[i].dup == fd) { lf->entries[i].dup = -1; PTHREAD_MUTEX_UNLOCK(&(lf->mutex)); return 0; } } PTHREAD_MUTEX_UNLOCK(&(lf->mutex)); fr_strerror_printf("Attempt to unlock file which does not exist"); return -1; }
int exfile_unlock(exfile_t *ef, int fd) { uint32_t i; for (i = 0; i < ef->max_entries; i++) { if (!ef->entries[i].filename) continue; if (ef->entries[i].dup == fd) { ef->entries[i].dup = -1; PTHREAD_MUTEX_UNLOCK(&(ef->mutex)); return 0; } } PTHREAD_MUTEX_UNLOCK(&(ef->mutex)); fr_strerror_printf("Attempt to unlock file which does not exist"); return -1; }
/* vpe_hardware_unsubcribe_v4l2_event: * **/ static int32_t vpe_hardware_unsubcribe_v4l2_event(vpe_hardware_t *vpehw) { int rc; struct v4l2_event_subscription sub; /* note: make sure to unlock this on each return path */ PTHREAD_MUTEX_LOCK(&(vpehw->mutex)); if (vpehw->event_subs_info.valid == TRUE) { vpehw->event_subs_info.valid = FALSE; sub.id = vpehw->event_subs_info.id; sub.type = vpehw->event_subs_info.type; rc = ioctl(vpehw->subdev_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); if (rc < 0) { CDBG_ERROR("%s:%d: v4l2 ioctl() failed, rc=%d\n", __func__, __LINE__, rc); PTHREAD_MUTEX_UNLOCK(&(vpehw->mutex)); return -EIO; } } PTHREAD_MUTEX_UNLOCK(&(vpehw->mutex)); return 0; }
/* vpe_hardware_process_streamoff: * **/ int32_t vpe_hardware_process_streamoff(vpe_hardware_t *vpehw, uint32_t identity) { int rc, i; struct msm_camera_v4l2_ioctl_t v4l2_ioctl; CDBG("%s:%d, identity=0x%x", __func__, __LINE__, identity); PTHREAD_MUTEX_LOCK(&(vpehw->mutex)); vpe_hardware_stream_status_t* stream_status = vpe_hardware_get_stream_status(vpehw, identity); if (!stream_status) { CDBG_ERROR("%s:%d: failed\n", __func__, __LINE__); PTHREAD_MUTEX_UNLOCK(&(vpehw->mutex)); return -EFAULT; } stream_status->stream_off_pending = TRUE; /* wait for all pending buffers to be processed */ while (stream_status->pending_buf != 0) { CDBG_LOW("%s:%d, waiting for pending buf, identity=0x%x, pending_buf=%d", __func__, __LINE__, identity, stream_status->pending_buf); pthread_cond_wait(&(vpehw->no_pending_cond), &(vpehw->mutex)); } stream_status->stream_off_pending = FALSE; stream_status->valid = FALSE; PTHREAD_MUTEX_UNLOCK(&(vpehw->mutex)); CDBG("%s:%d, pending buffers done, hw streaming off. identity=0x%x\n", __func__, __LINE__, identity); v4l2_ioctl.ioctl_ptr = (void *)&identity; v4l2_ioctl.len = sizeof(identity); rc = ioctl(vpehw->subdev_fd, VIDIOC_MSM_VPE_DEQUEUE_STREAM_BUFF_INFO, &v4l2_ioctl); if (rc < 0) { CDBG_ERROR("%s:%d: v4l2 ioctl() failed, rc=%d\n", __func__, __LINE__, rc); return -EIO; } CDBG("%s:%d, hw stream off done. identity=0x%x\n", __func__, __LINE__, identity); return 0; }
void _starpu_stack_push_task(struct starpu_stack_jobq_s *stack_queue, pthread_mutex_t *sched_mutex, pthread_cond_t *sched_cond, starpu_job_t task) { PTHREAD_MUTEX_LOCK(sched_mutex); total_number_of_jobs++; STARPU_TRACE_JOB_PUSH(task, 0); starpu_job_list_push_front(stack_queue->jobq, task); stack_queue->njobs++; stack_queue->nprocessed++; PTHREAD_COND_SIGNAL(sched_cond); PTHREAD_MUTEX_UNLOCK(sched_mutex); }
/** Find an element in the tree, returning the data, not the node * */ rbnode_t *rbtree_find(rbtree_t *tree, void const *data) { rbnode_t *current; PTHREAD_MUTEX_LOCK(tree); current = tree->root; while (current != NIL) { int result = tree->compare(data, current->data); if (result == 0) { PTHREAD_MUTEX_UNLOCK(tree); return current; } else { current = (result < 0) ? current->left : current->right; } } PTHREAD_MUTEX_UNLOCK(tree); return NULL; }
static int ddc_sync(void* data) { DVDecodeStreamConnect* connect = (DVDecodeStreamConnect*)data; int status; int workerResult = 0; int doneWaiting; if (!connect->frameWasReceived) { /* no work was required */ return 1; } /* reset for next time */ connect->frameWasReceived = 0; if (!connect->useWorkerThread) { /* work is already complete */ return 1; } /* TODO: timed wait to prevent eternal loop? */ /* wait until worker has processed the frame and is no longer busy */ doneWaiting = 0; while (!doneWaiting && !connect->stopped) { /* wait for worker */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); if (connect->workerIsBusy) { status = pthread_cond_wait(&connect->workerIsBusyCond, &connect->workerMutex); if (status != 0) { ml_log_error("DV connect worker thread failed to wait for condition\n"); /* TODO: don't try again? */ } } /* worker is not busy and no frame is waiting to be processed */ if (!connect->workerIsBusy && !connect->frameIsReady) { workerResult = connect->workerResult; doneWaiting = 1; } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); } return workerResult; }