int user_main(int argc, char **argv) { thrd_t t1, t2; if (argc > 1) N = atoi(argv[1]); atomic_init(&x, 0); thrd_create(&t1, (thrd_start_t)&a, NULL); thrd_create(&t2, (thrd_start_t)&a, NULL); thrd_join(t1); thrd_join(t2); MODEL_ASSERT(atomic_load(&x) == N * 2); return 0; }
/* ================================================================================== Funtion :setup_root_vnode Input :struct super_block *sb < this super block > struct vnode *v_root < root vnode to set up > Output :void Return :void Description :set up root vnode ================================================================================== */ LOCAL void setup_root_vnode(struct super_block *sb, struct vnode *v_root) { v_root->v_size = PAGESIZE; v_root->v_blocks = DIV_ROUNDUP(v_root->v_size, RAMFS_BLOCK_SIZE); v_root->v_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IRWXO | S_IXOTH; v_root->v_mode |= S_IFDIR; v_root->v_uid = 0; v_root->v_gid = 0; v_root->v_opflags = 0; v_root->v_bytes = 0; v_root->v_blkbits = sb->s_blocksize_bits; v_root->v_nlink = 2; atomic_init(&v_root->v_count, 1); //v_root->v_op = v_root->v_fops = &ramfs_dir_file_ope; }
int user_main(int argc, char **argv) { thrd_t t1, t2, t3; atomic_init(&x, 0); printf("Main thread: creating 3 threads\n"); thrd_create(&t1, (thrd_start_t)&a, NULL); thrd_create(&t2, (thrd_start_t)&b, NULL); thrd_create(&t3, (thrd_start_t)&c, NULL); thrd_join(t1); thrd_join(t2); thrd_join(t3); printf("Main thread is finished\n"); return 0; }
void __attribute__((constructor)) vcore_lib_init(void) { uintptr_t mmap_block; /* Note this is racy, but okay. The first time through, we are _S. * Also, this is the "lowest" level constructor for now, so we don't need * to call any other init functions after our run_once() call. This may * change in the future. */ init_once_racy(return); /* Need to alloc vcore0's transition stuff here (technically, just the TLS) * so that schedulers can use vcore0's transition TLS before it comes up in * vcore_entry() */ if (allocate_vcore_stack(0) || allocate_transition_tls(0)) goto vcore_lib_init_fail; /* Initialize our VCPD event queues' ucqs, two pages per ucq, 4 per vcore */ mmap_block = (uintptr_t)mmap(0, PGSIZE * 4 * max_vcores(), PROT_WRITE | PROT_READ, MAP_POPULATE | MAP_ANONYMOUS, -1, 0); /* Yeah, this doesn't fit in the error-handling scheme, but this whole * system doesn't really handle failure, and needs a rewrite involving less * mmaps/munmaps. */ assert(mmap_block); /* Note we may end up doing vcore 0's elsewhere, for _Ss, or else have a * separate ev_q for that. */ for (int i = 0; i < max_vcores(); i++) { /* four pages total for both ucqs from the big block (2 pages each) */ ucq_init_raw(&vcpd_of(i)->ev_mbox_public.ev_msgs, mmap_block + (4 * i ) * PGSIZE, mmap_block + (4 * i + 1) * PGSIZE); ucq_init_raw(&vcpd_of(i)->ev_mbox_private.ev_msgs, mmap_block + (4 * i + 2) * PGSIZE, mmap_block + (4 * i + 3) * PGSIZE); /* Set the lowest level entry point for each vcore. */ vcpd_of(i)->vcore_entry = (uintptr_t)__kernel_vcore_entry; } atomic_init(&vc_req_being_handled, 0); assert(!in_vcore_context()); vcore_libc_init(); return; vcore_lib_init_fail: assert(0); }
static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached, void *(*entry) (void *), void *data, int priority) { struct vlc_thread *th = malloc (sizeof (*th)); if (unlikely(th == NULL)) return ENOMEM; th->entry = entry; th->data = data; th->killable = false; /* not until vlc_entry() ! */ #if !VLC_WINSTORE_APP th->killed = false; #else atomic_init(&th->killed, false); #endif th->cleaners = NULL; /* When using the MSVCRT C library you have to use the _beginthreadex * function instead of CreateThread, otherwise you'll end up with * memory leaks and the signal functions not working (see Microsoft * Knowledge Base, article 104641) */ uintptr_t h = _beginthreadex (NULL, 0, vlc_entry, th, 0, NULL); if (h == 0) { int err = errno; free (th); return err; } if (detached) { CloseHandle((HANDLE)h); th->id = NULL; } else th->id = (HANDLE)h; if (p_handle != NULL) *p_handle = th; if (priority) SetThreadPriority (th->id, priority); return 0; }
static int reset_cport(unsigned int cportid, struct usbdev_s *dev) { struct cport_reset_priv *priv; priv = zalloc(sizeof(*priv)); if (!priv) { return -ENOMEM; } wd_static(&priv->timeout_wd); priv->dev = dev; /* a ref for the watchdog and one for the unipro stack */ atomic_init(&priv->refcount, 2); wd_start(&priv->timeout_wd, RESET_TIMEOUT_DELAY, cport_reset_timeout, 1, priv); return unipro_reset_cport(cportid, cport_reset_cb, priv); }
int sock_av_open(struct fid_domain *domain, struct fi_av_attr *attr, struct fid_av **av, void *context) { struct sock_domain *dom; struct sock_av *_av; // int ret; if (attr->name || attr->flags) return -FI_ENOSYS; dom = container_of(domain, struct sock_domain, dom_fid); _av = calloc(1, sizeof(*_av)); if (!_av) return -FI_ENOMEM; _av->av_fid.fid.fclass = FI_CLASS_AV; _av->av_fid.fid.context = context; _av->av_fid.fid.ops = &sock_av_fi_ops; switch (attr->type) { case FI_AV_MAP: // ret = sock_open_am(dom, attr, &_av, context); _av->av_fid.ops = &sock_am_ops; break; case FI_AV_TABLE: _av->av_fid.ops = &sock_at_ops; break; default: return -FI_ENOSYS; } #if 0 if (ret) return ret; #endif atomic_init(&_av->ref, 0); atomic_inc(&dom->ref); _av->dom = dom; _av->attr = *attr; *av = &_av->av_fid; return 0; }
/** Initializes a queue for use. * * \param aq A pointer to the aqueue structure * \param obj_size The size of an individual object in the queue * \param obj_count The number of objects to keep per page */ struct aqueue* aqueue_create( size_t size, size_t count ) { struct aqueue* aq = (struct aqueue*)kmalloc( sizeof(struct aqueue) ); if ( aq == NULL ) return NULL; atomic_init( &(aq->lock) ); aq->pages = 0; aq->obj_size = size; aq->obj_count = count; aq->position = 0; aq->last_position = 0; aq->page = NULL; aq->last_page = NULL; return aq; }
RatResult rat_workers_create(RatWorker** workers, RatPool* pool, size_t count) { RAT_ASSERT(workers); *workers = NULL; RatResult result = RAT_RESULT_SUCCESS; for(size_t i = 0; i < count; ++i) { // create the worker RatWorker* worker = malloc(sizeof(RatWorker)); if (!worker){ result = RAT_RESULT_OUT_OF_MEMORY; break; } // basic initialization worker->is_active = false; worker->pool = pool; worker->lock.pmutex_created = false; worker->wake_condition.pcond_created = false; worker->thread.pthread_created = false; atomic_init(&worker->work_count, 0); worker->work = NULL; worker->free_work = NULL; worker->incoming_work = NULL; worker->free_incoming_work = NULL; // setup internal linkage worker->next = *workers; *workers = worker; // initialize threading components result = rat_lock_init(&worker->lock); if (result != RAT_RESULT_SUCCESS){ break; } result = rat_condition_init(&worker->wake_condition); if (result != RAT_RESULT_SUCCESS){ break; } result = rat_thread_init(&worker->thread, rat_worker_thread, worker); if (result != RAT_RESULT_SUCCESS){ break; } worker->is_active = true; } // clean up on failure if (result != RAT_RESULT_SUCCESS) { RatResult result = rat_workers_destroy(workers); RAT_ASSERT(result == RAT_RESULT_SUCCESS); } return result; }
int sock_cntr_open(struct fid_domain *domain, struct fi_cntr_attr *attr, struct fid_cntr **cntr, void *context) { struct sock_domain *dom; struct sock_cntr *_cntr; int ret; if ((attr->events != FI_CNTR_EVENTS_COMP) || (attr->wait_obj != FI_WAIT_MUT_COND) || attr->flags) return -FI_ENOSYS; _cntr = calloc(1, sizeof(*_cntr)); if (!_cntr) return -FI_ENOMEM; ret = pthread_cond_init(&_cntr->cond, NULL); if (ret) goto err1; ret = pthread_mutex_init(&_cntr->mut, NULL); if (ret) goto err2; atomic_init(&_cntr->ref, 0); _cntr->cntr_fid.fid.fclass = FI_CLASS_CNTR; _cntr->cntr_fid.fid.context = context; _cntr->cntr_fid.fid.ops = &sock_cntr_fi_ops; _cntr->cntr_fid.ops = &sock_cntr_ops; _cntr->threshold = ~0; dom = container_of(domain, struct sock_domain, dom_fid); atomic_inc(&dom->ref); _cntr->dom = dom; *cntr = &_cntr->cntr_fid; return 0; err2: pthread_cond_destroy(&_cntr->cond); err1: free(_cntr); return -ret; }
/** * Initializes an interruption context. */ void vlc_interrupt_init(vlc_interrupt_t *ctx) { vlc_rwlock_wrlock(&vlc_interrupt_lock); assert(vlc_interrupt_refs < UINT_MAX); if (vlc_interrupt_refs++ == 0) #ifndef NDEBUG vlc_threadvar_create(&vlc_interrupt_var, vlc_interrupt_destructor); #else vlc_threadvar_create(&vlc_interrupt_var, NULL); #endif vlc_rwlock_unlock(&vlc_interrupt_lock); vlc_mutex_init(&ctx->lock); ctx->interrupted = false; atomic_init(&ctx->killed, false); #ifndef NDEBUG ctx->attached = false; #endif ctx->callback = NULL; }
char* wbuf_init(const int npages) { int i; char *buf; atomic_llong *map; if (npages % 64) return NULL; buf = malloc(WBUF_MAPBYTES(npages)+WBUF_SIZE(npages)); map = (atomic_llong*)buf; memset(buf+WBUF_MAPBYTES(npages), 0, WBUF_SIZE(npages)); for (i = 0; i < WBUF_MAP_ELEMENTS(npages); i++) { atomic_init(&map[i],0); } return buf; }
static int sock_fabric(struct fi_fabric_attr *attr, struct fid_fabric **fabric, void *context) { struct sock_fabric *fab; if (strcmp(attr->name, sock_fab_name)) return -FI_ENODATA; fab = calloc(1, sizeof(*fab)); if (!fab) return -FI_ENOMEM; fab->fab_fid.fid.fclass = FI_CLASS_FABRIC; fab->fab_fid.fid.context = context; fab->fab_fid.fid.ops = &sock_fab_fi_ops; fab->fab_fid.ops = &sock_fab_ops; *fabric = &fab->fab_fid; atomic_init(&fab->ref, 0); return 0; }
void vcore_init(void) { uintptr_t mmap_block; /* Note this is racy, but okay. The first time through, we are _S */ init_once_racy(return); /* Need to alloc vcore0's transition stuff here (technically, just the TLS) * so that schedulers can use vcore0's transition TLS before it comes up in * vcore_entry() */ if(allocate_transition_stack(0) || allocate_transition_tls(0)) goto vcore_init_fail; /* Initialize our VCPD event queues' ucqs, two pages per ucq, 4 per vcore */ mmap_block = (uintptr_t)mmap(0, PGSIZE * 4 * max_vcores(), PROT_WRITE | PROT_READ, MAP_POPULATE | MAP_ANONYMOUS, -1, 0); /* Yeah, this doesn't fit in the error-handling scheme, but this whole * system doesn't really handle failure, and needs a rewrite involving less * mmaps/munmaps. */ assert(mmap_block); /* Note we may end up doing vcore 0's elsewhere, for _Ss, or else have a * separate ev_q for that. */ for (int i = 0; i < max_vcores(); i++) { /* four pages total for both ucqs from the big block (2 pages each) */ ucq_init_raw(&vcpd_of(i)->ev_mbox_public.ev_msgs, mmap_block + (4 * i ) * PGSIZE, mmap_block + (4 * i + 1) * PGSIZE); ucq_init_raw(&vcpd_of(i)->ev_mbox_private.ev_msgs, mmap_block + (4 * i + 2) * PGSIZE, mmap_block + (4 * i + 3) * PGSIZE); } atomic_init(&vc_req_being_handled, 0); assert(!in_vcore_context()); /* no longer need to enable notifs on vcore 0, it is set like that by * default (so you drop into vcore context immediately on transtioning to * _M) */ vc_initialized = TRUE; return; vcore_init_fail: assert(0); }
struct dnet_trans *dnet_trans_alloc(struct dnet_node *n, uint64_t size) { struct dnet_trans *t; t = calloc(1, sizeof(struct dnet_trans) + size); if (!t) goto err_out_exit; t->alloc_size = size; t->n = n; atomic_init(&t->refcnt, 1); INIT_LIST_HEAD(&t->trans_list_entry); gettimeofday(&t->start, NULL); return t; err_out_exit: return NULL; }
static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s) { FFAMediaCodec *codec = s->codec; int status; s->output_buffer_count = 0; s->draining = 0; s->flushing = 0; s->eos = 0; atomic_fetch_add(&s->serial, 1); atomic_init(&s->hw_buffer_count, 0); status = ff_AMediaCodec_flush(codec); if (status < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to flush codec\n"); return AVERROR_EXTERNAL; } return 0; }
int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local, const sock_udp_ep_t *remote, uint16_t flags) { int res; (void)flags; assert((sock != NULL)); assert((remote == NULL) || (remote->port != 0)); if (sock->sock.input_callback != NULL) { sock_udp_close(sock); } mutex_init(&sock->mutex); mutex_lock(&sock->mutex); mbox_init(&sock->mbox, sock->mbox_queue, SOCK_MBOX_SIZE); atomic_init(&sock->receivers, 0); if ((res = _reg(&sock->sock, sock, _input_callback, local, remote)) < 0) { sock->sock.input_callback = NULL; } mutex_unlock(&sock->mutex); return res; }
QueueResult queue_push(queue_p q, void *data) { assert(q); /* create the new tail */ node *new_tail = malloc(sizeof(node) + q->item_size); if (!new_tail) { return QUEUE_OUT_OF_MEMORY; } atomic_init(&new_tail->next, 0); memcpy(new_tail + 1, data, q->item_size); /* swap the new tail with the old */ node *old_tail = (node *) atomic_exchange(&q->tail, new_tail->next); /* link the old tail to the new */ if (old_tail) { atomic_store(&old_tail->next, new_tail->next); } else { atomic_store(&q->head, new_tail->next); } return QUEUE_SUCCESS; }
struct vlc_vaapi_instance * vlc_vaapi_InitializeInstance(vlc_object_t *o, VADisplay dpy, VANativeDisplay native, vlc_vaapi_native_destroy_cb native_destroy_cb) { int major = 0, minor = 0; VA_CALL(o, vaInitialize, dpy, &major, &minor); struct vlc_vaapi_instance *inst = malloc(sizeof(*inst)); if (unlikely(inst == NULL)) goto error; inst->dpy = dpy; inst->native = native; inst->native_destroy_cb = native_destroy_cb; atomic_init(&inst->pic_refcount, 1); return inst; error: vaTerminate(dpy); if (native != NULL && native_destroy_cb != NULL) native_destroy_cb(native); return NULL; }
static int usdf_dom_rdc_alloc_data(struct usdf_domain *udp) { struct usdf_rdm_connection *rdc; int ret; int i; udp->dom_rdc_hashtab = calloc(USDF_RDM_HASH_SIZE, sizeof(*udp->dom_rdc_hashtab)); if (udp->dom_rdc_hashtab == NULL) { return -FI_ENOMEM; } SLIST_INIT(&udp->dom_rdc_free); atomic_init(&udp->dom_rdc_free_cnt, 0); for (i = 0; i < USDF_RDM_FREE_BLOCK; ++i) { rdc = calloc(1, sizeof(*rdc)); if (rdc == NULL) { return -FI_ENOMEM; } ret = usdf_timer_alloc(usdf_rdm_rdc_timeout, rdc, &rdc->dc_timer); if (ret != 0) { free(rdc); return ret; } rdc->dc_flags = USDF_DCS_UNCONNECTED | USDF_DCF_NEW_RX; rdc->dc_next_rx_seq = 0; rdc->dc_next_tx_seq = 0; rdc->dc_last_rx_ack = rdc->dc_next_tx_seq - 1; TAILQ_INIT(&rdc->dc_wqe_posted); TAILQ_INIT(&rdc->dc_wqe_sent); SLIST_INSERT_HEAD(&udp->dom_rdc_free, rdc, dc_addr_link); atomic_inc(&udp->dom_rdc_free_cnt); } udp->dom_rdc_total = USDF_RDM_FREE_BLOCK; return 0; }
/** * @brief Initialize one UniPro cport */ static int unipro_init_cport(unsigned int cportid) { struct cport *cport = cport_handle(cportid); if (!cport) { return -EINVAL; } if (cport->connected) return 0; _unipro_reset_cport(cportid); atomic_init(&cport->inflight_buf_count, 0); #if defined(CONFIG_APBRIDGEA) cport->max_inflight_buf_count = 1; #else cport->max_inflight_buf_count = CONFIG_TSB_UNIPRO_MAX_INFLIGHT_BUFCOUNT; #endif cport->switch_buf_on_free = false; cport->rx_buf = unipro_rxbuf_alloc(cportid); if (!cport->rx_buf) { lowsyslog("unipro: couldn't allocate initial buffer for CP%u\n", cportid); return -ENOMEM; } unipro_switch_rxbuf(cportid, cport->rx_buf); #ifdef UNIPRO_DEBUG unipro_info(); #endif return 0; }
/***************************************************************************** * Create *****************************************************************************/ static int Create( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; const vlc_chroma_description_t *p_chroma = vlc_fourcc_GetChromaDescription( p_filter->fmt_in.video.i_chroma ); if( p_chroma == NULL || p_chroma->plane_count == 0 ) return VLC_EGENERIC; /* Allocate structure */ filter_sys_t *p_sys = malloc( sizeof( filter_sys_t ) ); if( p_sys == NULL ) return VLC_ENOMEM; p_filter->p_sys = p_sys; p_sys->p_tmp = picture_NewFromFormat( &p_filter->fmt_in.video ); if( !p_sys->p_tmp ) { free( p_sys ); return VLC_ENOMEM; } p_sys->b_first = true; p_filter->pf_video_filter = Filter; config_ChainParse( p_filter, FILTER_PREFIX, ppsz_filter_options, p_filter->p_cfg ); atomic_init( &p_sys->i_factor, var_CreateGetIntegerCommand( p_filter, FILTER_PREFIX "factor" ) ); var_AddCallback( p_filter, FILTER_PREFIX "factor", MotionBlurCallback, p_sys ); return VLC_SUCCESS; }
static int _open(const char *path, const char *name, const char *id, void *data) { bin_t *bin = data; prog_t *handle = (void *)bin - offsetof(prog_t, bin); (void)name; if(bin->path) free(bin->path); bin->path = strdup(path); // jack init if(_jack_init(handle, id)) { bin->ui_driver.close(bin); return -1; } // synthpod init bin->app_driver.sample_rate = jack_get_sample_rate(handle->client); bin->app_driver.max_block_size = jack_get_buffer_size(handle->client); bin->app_driver.min_block_size = 1; bin->app_driver.seq_size = MAX(handle->seq_size, jack_port_type_get_buffer_size(handle->client, JACK_DEFAULT_MIDI_TYPE)); // app init bin->app = sp_app_new(NULL, &bin->app_driver, bin); // jack activate atomic_init(&handle->kill, 0); jack_activate(handle->client); //TODO check sp_ui_bundle_load(bin->ui, bin->path, 1); return 0; // success }
int usdf_cq_make_soft(struct usdf_cq *cq) { struct fi_ops_cq *hard_ops; struct fi_ops_cq *soft_ops; struct usdf_cq_hard *hcq; struct usd_cq *ucq; size_t comp_size; void (*rtn)(struct usdf_cq_hard *hcq); switch (cq->cq_attr.format) { case FI_CQ_FORMAT_CONTEXT: hard_ops = &usdf_cq_context_ops; soft_ops = &usdf_cq_context_soft_ops; comp_size = sizeof(struct fi_cq_entry); rtn = usdf_progress_hard_cq_context; break; case FI_CQ_FORMAT_MSG: hard_ops = &usdf_cq_msg_ops; soft_ops = &usdf_cq_msg_soft_ops; comp_size = sizeof(struct fi_cq_msg_entry); rtn = usdf_progress_hard_cq_msg; break; case FI_CQ_FORMAT_DATA: hard_ops = &usdf_cq_data_ops; soft_ops = &usdf_cq_data_soft_ops; comp_size = sizeof(struct fi_cq_data_entry); rtn = usdf_progress_hard_cq_data; break; default: return 0; } if (cq->cq_fid.ops == hard_ops) { /* save the CQ before we trash the union */ ucq = cq->c.hard.cq_cq; /* fill in the soft part of union */ TAILQ_INIT(&cq->c.soft.cq_list); cq->c.soft.cq_comps = calloc(cq->cq_attr.size, comp_size); if (cq->c.soft.cq_comps == NULL) { return -FI_ENOMEM; } cq->c.soft.cq_end = (void *)((uintptr_t)cq->c.soft.cq_comps + (cq->cq_attr.size * comp_size)); cq->c.soft.cq_head = cq->c.soft.cq_comps; cq->c.soft.cq_tail = cq->c.soft.cq_comps; /* need to add hard queue to list? */ if (ucq != NULL) { hcq = malloc(sizeof(*hcq)); if (hcq == NULL) { free(cq->c.soft.cq_comps); cq->c.hard.cq_cq = ucq; /* restore */ return -FI_ENOMEM; } hcq->cqh_cq = cq; hcq->cqh_ucq = ucq; hcq->cqh_progress = rtn; atomic_init(&hcq->cqh_refcnt, atomic_get(&cq->cq_refcnt)); TAILQ_INSERT_HEAD(&cq->c.soft.cq_list, hcq, cqh_link); } cq->cq_fid.ops = soft_ops; } return 0; }
/* TODO: reintroduce barrier's ops to deal with case-specific treatment */ error_t barrier_wait(struct barrier_s *barrier) { register uint_t ticket; register uint_t index; register uint_t wqdbsz; register wqdb_t *wqdb; register bool_t isShared; struct thread_s *this; uint_t tm_now; tm_now = cpu_time_stamp(); this = current_thread; index = this->info.order; ticket = 0; isShared = (barrier->owner == NULL) ? true : false; if((barrier->signature != BARRIER_ID) || ((isShared == false) && (barrier->owner != this->task))) return EINVAL; wqdbsz = PMM_PAGE_SIZE / sizeof(wqdb_record_t); if(isShared) { spinlock_lock(&barrier->lock); index = barrier->index ++; ticket = barrier->count - index; } wqdb = barrier->wqdb_tbl[index / wqdbsz]; #if CONFIG_USE_SCHED_LOCKS wqdb->tbl[index % wqdbsz].listner = (void*)this; #else uint_t irq_state; cpu_disable_all_irq(&irq_state); /* To prevent against any scheduler intervention */ wqdb->tbl[index % wqdbsz].event = sched_event_make (this, SCHED_OP_WAKEUP); wqdb->tbl[index % wqdbsz].listner = sched_get_listner(this, SCHED_OP_WAKEUP); #endif if(isShared == false) ticket = atomic_add(&barrier->waiting, -1); if(ticket == 1) { #if !(CONFIG_USE_SCHED_LOCKS) cpu_restore_irq(irq_state); #endif barrier->tm_last = tm_now; wqdb->tbl[index % wqdbsz].listner = NULL; if(isShared) { barrier->index = 0; spinlock_unlock(&barrier->lock); } else atomic_init(&barrier->waiting, barrier->count); barrier_do_broadcast(barrier); return PTHREAD_BARRIER_SERIAL_THREAD; } if(ticket == barrier->count) barrier->tm_first = tm_now; spinlock_unlock_nosched(&barrier->lock); sched_sleep(this); #if !(CONFIG_USE_SCHED_LOCKS) cpu_restore_irq(irq_state); #endif return 0; }
/***************************************************************************** * InitVideo: initialize the video decoder ***************************************************************************** * the ffmpeg codec will be opened, some memory allocated. The vout is not yet * opened (done after the first decoded frame). *****************************************************************************/ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, const AVCodec *p_codec ) { decoder_sys_t *p_sys; int i_val; /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL ) return VLC_ENOMEM; p_sys->p_context = p_context; p_sys->p_codec = p_codec; p_sys->b_delayed_open = true; p_sys->p_va = NULL; vlc_sem_init( &p_sys->sem_mt, 0 ); /* ***** Fill p_context with init values ***** */ p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ? p_dec->fmt_in.i_original_fourcc : p_dec->fmt_in.i_codec ); /* ***** Get configuration of ffmpeg plugin ***** */ p_context->workaround_bugs = var_InheritInteger( p_dec, "avcodec-workaround-bugs" ); p_context->err_recognition = var_InheritInteger( p_dec, "avcodec-error-resilience" ); if( var_CreateGetBool( p_dec, "grayscale" ) ) p_context->flags |= CODEC_FLAG_GRAY; /* ***** Output always the frames ***** */ p_context->flags |= CODEC_FLAG_OUTPUT_CORRUPT; i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" ); if( i_val >= 4 ) p_context->skip_loop_filter = AVDISCARD_ALL; else if( i_val == 3 ) p_context->skip_loop_filter = AVDISCARD_NONKEY; else if( i_val == 2 ) p_context->skip_loop_filter = AVDISCARD_BIDIR; else if( i_val == 1 ) p_context->skip_loop_filter = AVDISCARD_NONREF; if( var_CreateGetBool( p_dec, "avcodec-fast" ) ) p_context->flags2 |= CODEC_FLAG2_FAST; /* ***** libavcodec frame skipping ***** */ p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" ); i_val = var_CreateGetInteger( p_dec, "avcodec-skip-frame" ); if( i_val >= 4 ) p_context->skip_frame = AVDISCARD_ALL; else if( i_val == 3 ) p_context->skip_frame = AVDISCARD_NONKEY; else if( i_val == 2 ) p_context->skip_frame = AVDISCARD_BIDIR; else if( i_val == 1 ) p_context->skip_frame = AVDISCARD_NONREF; else if( i_val == -1 ) p_context->skip_frame = AVDISCARD_NONE; else p_context->skip_frame = AVDISCARD_DEFAULT; p_sys->i_skip_frame = p_context->skip_frame; i_val = var_CreateGetInteger( p_dec, "avcodec-skip-idct" ); if( i_val >= 4 ) p_context->skip_idct = AVDISCARD_ALL; else if( i_val == 3 ) p_context->skip_idct = AVDISCARD_NONKEY; else if( i_val == 2 ) p_context->skip_idct = AVDISCARD_BIDIR; else if( i_val == 1 ) p_context->skip_idct = AVDISCARD_NONREF; else if( i_val == -1 ) p_context->skip_idct = AVDISCARD_NONE; else p_context->skip_idct = AVDISCARD_DEFAULT; /* ***** libavcodec direct rendering ***** */ p_sys->b_direct_rendering = false; atomic_init(&p_sys->b_dr_failure, false); if( var_CreateGetBool( p_dec, "avcodec-dr" ) && (p_codec->capabilities & CODEC_CAP_DR1) && /* No idea why ... but this fixes flickering on some TSCC streams */ p_sys->p_codec->id != AV_CODEC_ID_TSCC && p_sys->p_codec->id != AV_CODEC_ID_CSCD && p_sys->p_codec->id != AV_CODEC_ID_CINEPAK ) { /* Some codecs set pix_fmt only after the 1st frame has been decoded, * so we need to do another check in ffmpeg_GetFrameBuf() */ p_sys->b_direct_rendering = true; } /* libavcodec doesn't properly release old pictures when frames are skipped */ //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false; if( p_sys->b_direct_rendering ) { msg_Dbg( p_dec, "trying to use direct rendering" ); p_context->flags |= CODEC_FLAG_EMU_EDGE; } else { msg_Dbg( p_dec, "direct rendering is disabled" ); } p_context->get_format = ffmpeg_GetFormat; /* Always use our get_buffer wrapper so we can calculate the * PTS correctly */ p_context->get_buffer2 = lavc_GetFrame; p_context->refcounted_frames = true; p_context->opaque = p_dec; #ifdef HAVE_AVCODEC_MT int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" ); if( i_thread_count <= 0 ) { i_thread_count = vlc_GetCPUCount(); if( i_thread_count > 1 ) i_thread_count++; //FIXME: take in count the decoding time i_thread_count = __MIN( i_thread_count, 4 ); } i_thread_count = __MIN( i_thread_count, 16 ); msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count ); p_context->thread_count = i_thread_count; p_context->thread_safe_callbacks = true; switch( p_codec->id ) { case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_H263: p_context->thread_type = 0; break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: p_context->thread_type &= ~FF_THREAD_SLICE; /* fall through */ # if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0)) case AV_CODEC_ID_H264: case AV_CODEC_ID_VC1: case AV_CODEC_ID_WMV3: p_context->thread_type &= ~FF_THREAD_FRAME; # endif default: break; } /* Workaround: frame multithreading is not compatible with * DXVA2. When a frame is being copied to host memory, the frame * is locked and cannot be used as a reference frame * simultaneously and thus decoding fails for some frames. This * causes major image corruption. */ # if defined(_WIN32) char *avcodec_hw = var_InheritString( p_dec, "avcodec-hw" ); if( avcodec_hw == NULL || strcasecmp( avcodec_hw, "none" ) ) { msg_Warn( p_dec, "threaded frame decoding is not compatible with DXVA2, disabled" ); p_context->thread_type &= ~FF_THREAD_FRAME; } free( avcodec_hw ); # endif if( p_context->thread_type & FF_THREAD_FRAME ) p_dec->i_extra_picture_buffers = 2 * p_context->thread_count; #endif /* ***** misc init ***** */ p_sys->i_pts = VLC_TS_INVALID; p_sys->b_first_frame = true; p_sys->b_flush = false; p_sys->i_late_frames = 0; /* Set output properties */ p_dec->fmt_out.i_cat = VIDEO_ES; if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ) { /* we are doomed. but not really, because most codecs set their pix_fmt later on */ p_dec->fmt_out.i_codec = VLC_CODEC_I420; } p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; p_dec->fmt_out.video.orientation = p_dec->fmt_in.video.orientation; if( p_dec->fmt_in.video.p_palette ) { p_sys->palette_sent = false; p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) ); if( p_dec->fmt_out.video.p_palette ) *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette; } else p_sys->palette_sent = true; /* ***** init this codec with special data ***** */ ffmpeg_InitCodec( p_dec ); /* ***** Open the codec ***** */ if( OpenVideoCodec( p_dec ) < 0 ) { vlc_sem_destroy( &p_sys->sem_mt ); free( p_sys ); return VLC_EGENERIC; } p_dec->pf_decode_video = DecodeVideo; if ( p_dec->fmt_in.i_codec == VLC_CODEC_VP9 ) p_dec->b_need_packetized = true; return VLC_SUCCESS; }
error_t barrier_init(struct barrier_s *barrier, uint_t count, uint_t scope) { struct page_s *page; uint_t wqdbsz; uint_t i; error_t err; kmem_req_t req; wqdbsz = PMM_PAGE_SIZE / sizeof(wqdb_record_t); if(count == 0) return EINVAL; if(current_task->threads_limit > (BARRIER_WQDB_NR*wqdbsz)) { printk(INFO, "INFO: %s: pid %d, cpu %d, task threads limit exceed barrier ressources of %d\n", __FUNCTION__, current_task->pid, cpu_get_id(), BARRIER_WQDB_NR*wqdbsz); return ENOMEM; } if(count > BARRIER_WQDB_NR*wqdbsz) return ENOMEM; barrier->owner = (scope == BARRIER_INIT_PRIVATE) ? current_task : NULL; #if ARCH_HAS_BARRIERS barrier->cluster = current_cluster; event_set_handler(&barrier->event, &barrier_broadcast_event); event_set_argument(&barrier->event, barrier); barrier->hwid = arch_barrier_init(barrier->cluster, &barrier->event, count); if(barrier->hwid < 0) return ENOMEM; /* TODO: we can use software barrier instead */ #else if(barrier->owner != NULL) atomic_init(&barrier->waiting, count); else { spinlock_init(&barrier->lock, "barrier"); barrier->index = 0; } #endif /* ARCH_HAS_BARRIERS */ req.type = KMEM_PAGE; req.size = 0; req.flags = AF_USER | AF_ZERO; err = 0; for(i = 0; i < BARRIER_WQDB_NR; i++) { page = kmem_alloc(&req); if(page == NULL) { err = ENOMEM; break; } barrier->wqdb_tbl[i] = ppm_page2addr(page); barrier->pages_tbl[i] = page; } if(err) { err = i; for(i = 0; i < err; i++) { req.ptr = barrier->pages_tbl[i]; kmem_free(&req); } return ENOMEM; } barrier->count = count; barrier->signature = BARRIER_ID; barrier->state[0] = 0; barrier->state[1] = 0; barrier->phase = 0; barrier->name = "Barrier-Sync"; return 0; }
input_preparser_t* input_preparser_New( vlc_object_t *parent ) { input_preparser_t* preparser = malloc( sizeof *preparser ); struct background_worker_config conf = { .default_timeout = VLC_TICK_FROM_MS(var_InheritInteger( parent, "preparse-timeout" )), .max_threads = var_InheritInteger( parent, "preparse-threads" ), .pf_start = PreparserOpenInput, .pf_probe = PreparserProbeInput, .pf_stop = PreparserCloseInput, .pf_release = ReqReleaseVoid, .pf_hold = ReqHoldVoid }; if( likely( preparser ) ) preparser->worker = background_worker_New( preparser, &conf ); if( unlikely( !preparser || !preparser->worker ) ) { free( preparser ); return NULL; } preparser->owner = parent; preparser->fetcher = input_fetcher_New( parent ); atomic_init( &preparser->deactivated, false ); if( unlikely( !preparser->fetcher ) ) msg_Warn( parent, "unable to create art fetcher" ); return preparser; } void input_preparser_Push( input_preparser_t *preparser, input_item_t *item, input_item_meta_request_option_t i_options, const input_preparser_callbacks_t *cbs, void *cbs_userdata, int timeout, void *id ) { if( atomic_load( &preparser->deactivated ) ) return; vlc_mutex_lock( &item->lock ); enum input_item_type_e i_type = item->i_type; int b_net = item->b_net; vlc_mutex_unlock( &item->lock ); switch( i_type ) { case ITEM_TYPE_NODE: case ITEM_TYPE_FILE: case ITEM_TYPE_DIRECTORY: case ITEM_TYPE_PLAYLIST: if( !b_net || i_options & META_REQUEST_OPTION_SCOPE_NETWORK ) break; /* fallthrough */ default: if (cbs && cbs->on_preparse_ended) cbs->on_preparse_ended(item, ITEM_PREPARSE_SKIPPED, cbs_userdata); return; } struct input_preparser_req_t *req = ReqCreate(item, cbs, cbs_userdata); if (background_worker_Push(preparser->worker, req, id, timeout)) if (req->cbs && cbs->on_preparse_ended) cbs->on_preparse_ended(item, ITEM_PREPARSE_FAILED, cbs_userdata); ReqRelease(req); } void input_preparser_fetcher_Push( input_preparser_t *preparser, input_item_t *item, input_item_meta_request_option_t options, const input_fetcher_callbacks_t *cbs, void *cbs_userdata ) { if( preparser->fetcher ) input_fetcher_Push( preparser->fetcher, item, options, cbs, cbs_userdata ); } void input_preparser_Cancel( input_preparser_t *preparser, void *id ) { background_worker_Cancel( preparser->worker, id ); }
/** * Creates an audio output */ int aout_DecNew( audio_output_t *p_aout, const audio_sample_format_t *p_format, const audio_replay_gain_t *p_replay_gain, const aout_request_vout_t *p_request_vout ) { /* Sanitize audio format */ unsigned i_channels = aout_FormatNbChannels( p_format ); if( i_channels != p_format->i_channels && AOUT_FMT_LINEAR( p_format ) ) { msg_Err( p_aout, "incompatible audio channels count with layout mask" ); return -1; } if( p_format->i_rate > 352800 ) { msg_Err( p_aout, "excessive audio sample frequency (%u)", p_format->i_rate ); return -1; } if( p_format->i_rate < 4000 ) { msg_Err( p_aout, "too low audio sample frequency (%u)", p_format->i_rate ); return -1; } var_Create (p_aout, "stereo-mode", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); vlc_value_t txt; txt.psz_string = _("Stereo audio mode"); var_Change (p_aout, "stereo-mode", VLC_VAR_SETTEXT, &txt, NULL); aout_owner_t *owner = aout_owner(p_aout); /* TODO: reduce lock scope depending on decoder's real need */ aout_OutputLock (p_aout); /* Create the audio output stream */ owner->volume = aout_volume_New (p_aout, p_replay_gain); atomic_store (&owner->restart, 0); owner->input_format = *p_format; owner->mixer_format = owner->input_format; owner->request_vout = *p_request_vout; if (aout_OutputNew (p_aout, &owner->mixer_format)) goto error; aout_volume_SetFormat (owner->volume, owner->mixer_format.i_format); /* Create the audio filtering "input" pipeline */ owner->filters = aout_FiltersNew (p_aout, p_format, &owner->mixer_format, &owner->request_vout); if (owner->filters == NULL) { aout_OutputDelete (p_aout); error: aout_volume_Delete (owner->volume); owner->volume = NULL; aout_OutputUnlock (p_aout); var_Destroy (p_aout, "stereo-mode"); return -1; } owner->sync.end = VLC_TS_INVALID; owner->sync.resamp_type = AOUT_RESAMPLING_NONE; owner->sync.discontinuity = true; aout_OutputUnlock (p_aout); atomic_init (&owner->buffers_lost, 0); atomic_init (&owner->buffers_played, 0); return 0; }
int picture_Setup( picture_t *p_picture, video_format_t *fmt ) { /* Store default values */ p_picture->i_planes = 0; for( unsigned i = 0; i < VOUT_MAX_PLANES; i++ ) { plane_t *p = &p_picture->p[i]; p->p_pixels = NULL; p->i_pixel_pitch = 0; } atomic_init( &p_picture->gc.refcount, 0 ); p_picture->gc.pf_destroy = NULL; p_picture->gc.p_sys = NULL; p_picture->i_nb_fields = 2; video_format_Setup( &p_picture->format, fmt->i_chroma, fmt->i_width, fmt->i_height, fmt->i_visible_width, fmt->i_visible_height, fmt->i_sar_num, fmt->i_sar_den ); const vlc_chroma_description_t *p_dsc = vlc_fourcc_GetChromaDescription( p_picture->format.i_chroma ); if( !p_dsc ) return VLC_EGENERIC; /* We want V (width/height) to respect: (V * p_dsc->p[i].w.i_num) % p_dsc->p[i].w.i_den == 0 (V * p_dsc->p[i].w.i_num/p_dsc->p[i].w.i_den * p_dsc->i_pixel_size) % 16 == 0 Which is respected if you have V % lcm( p_dsc->p[0..planes].w.i_den * 16) == 0 */ int i_modulo_w = 1; int i_modulo_h = 1; unsigned int i_ratio_h = 1; for( unsigned i = 0; i < p_dsc->plane_count; i++ ) { i_modulo_w = LCM( i_modulo_w, 16 * p_dsc->p[i].w.den ); i_modulo_h = LCM( i_modulo_h, 16 * p_dsc->p[i].h.den ); if( i_ratio_h < p_dsc->p[i].h.den ) i_ratio_h = p_dsc->p[i].h.den; } i_modulo_h = LCM( i_modulo_h, 32 ); const int i_width_aligned = ( fmt->i_width + i_modulo_w - 1 ) / i_modulo_w * i_modulo_w; const int i_height_aligned = ( fmt->i_height + i_modulo_h - 1 ) / i_modulo_h * i_modulo_h; const int i_height_extra = 2 * i_ratio_h; /* This one is a hack for some ASM functions */ for( unsigned i = 0; i < p_dsc->plane_count; i++ ) { plane_t *p = &p_picture->p[i]; p->i_lines = (i_height_aligned + i_height_extra ) * p_dsc->p[i].h.num / p_dsc->p[i].h.den; p->i_visible_lines = fmt->i_visible_height * p_dsc->p[i].h.num / p_dsc->p[i].h.den; p->i_pitch = i_width_aligned * p_dsc->p[i].w.num / p_dsc->p[i].w.den * p_dsc->pixel_size; p->i_visible_pitch = fmt->i_visible_width * p_dsc->p[i].w.num / p_dsc->p[i].w.den * p_dsc->pixel_size; p->i_pixel_pitch = p_dsc->pixel_size; assert( (p->i_pitch % 16) == 0 ); } p_picture->i_planes = p_dsc->plane_count; return VLC_SUCCESS; }