tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pthread.c (4596B)


      1 /*
      2 * Copyright (c) 2004 Roman Shaposhnik
      3 * Copyright (c) 2008 Alexander Strange (astrange@ithinksw.com)
      4 *
      5 * Many thanks to Steven M. Schultz for providing clever ideas and
      6 * to Michael Niedermayer <michaelni@gmx.at> for writing initial
      7 * implementation.
      8 *
      9 * This file is part of FFmpeg.
     10 *
     11 * FFmpeg is free software; you can redistribute it and/or
     12 * modify it under the terms of the GNU Lesser General Public
     13 * License as published by the Free Software Foundation; either
     14 * version 2.1 of the License, or (at your option) any later version.
     15 *
     16 * FFmpeg is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19 * Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public
     22 * License along with FFmpeg; if not, write to the Free Software
     23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     24 */
     25 
     26 /**
     27 * @file
     28 * Multithreading support functions
     29 * @see doc/multithreading.txt
     30 */
     31 
     32 #include "libavutil/thread.h"
     33 
     34 #include "avcodec.h"
     35 #include "avcodec_internal.h"
     36 #include "codec_internal.h"
     37 #include "pthread_internal.h"
     38 #include "thread.h"
     39 
     40 /**
     41 * Set the threading algorithms used.
     42 *
     43 * Threading requires more than one thread.
     44 * Frame threading requires entire frames to be passed to the codec,
     45 * and introduces extra decoding delay, so is incompatible with low_delay.
     46 *
     47 * @param avctx The context.
     48 */
     49 static void validate_thread_parameters(AVCodecContext *avctx)
     50 {
     51    int frame_threading_supported = (avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)
     52                                && !(avctx->flags  & AV_CODEC_FLAG_LOW_DELAY)
     53                                && !(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS);
     54    if (avctx->thread_count == 1) {
     55        avctx->active_thread_type = 0;
     56    } else if (frame_threading_supported && (avctx->thread_type & FF_THREAD_FRAME)) {
     57        avctx->active_thread_type = FF_THREAD_FRAME;
     58    } else if (avctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS &&
     59               avctx->thread_type & FF_THREAD_SLICE) {
     60        avctx->active_thread_type = FF_THREAD_SLICE;
     61    } else if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_AUTO_THREADS)) {
     62        avctx->thread_count       = 1;
     63        avctx->active_thread_type = 0;
     64    }
     65 
     66    if (avctx->thread_count > MAX_AUTO_THREADS)
     67        av_log(avctx, AV_LOG_WARNING,
     68               "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
     69               avctx->thread_count, MAX_AUTO_THREADS);
     70 }
     71 
     72 int ff_thread_init(AVCodecContext *avctx)
     73 {
     74    validate_thread_parameters(avctx);
     75 
     76    if (avctx->active_thread_type&FF_THREAD_SLICE)
     77        return ff_slice_thread_init(avctx);
     78    else if (avctx->active_thread_type&FF_THREAD_FRAME)
     79        return ff_frame_thread_init(avctx);
     80 
     81    return 0;
     82 }
     83 
     84 void ff_thread_free(AVCodecContext *avctx)
     85 {
     86    if (avctx->active_thread_type&FF_THREAD_FRAME)
     87        ff_frame_thread_free(avctx, avctx->thread_count);
     88    else
     89        ff_slice_thread_free(avctx);
     90 }
     91 
     92 av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
     93 {
     94    unsigned cnt = *(unsigned*)((char*)obj + offsets[0]);
     95    const unsigned *cur_offset = offsets;
     96 
     97    *(unsigned*)((char*)obj + offsets[0]) = 0;
     98 
     99    for (; *(++cur_offset) != THREAD_SENTINEL && cnt; cnt--)
    100        pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset));
    101    for (; *(++cur_offset) != THREAD_SENTINEL && cnt; cnt--)
    102        pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset));
    103 }
    104 
    105 av_cold int ff_pthread_init(void *obj, const unsigned offsets[])
    106 {
    107    const unsigned *cur_offset = offsets;
    108    unsigned cnt = 0;
    109    int err;
    110 
    111 #define PTHREAD_INIT_LOOP(type)                                               \
    112    for (; *(++cur_offset) != THREAD_SENTINEL; cnt++) {                       \
    113        pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset);      \
    114        err = pthread_ ## type ## _init(dst, NULL);                           \
    115        if (err) {                                                            \
    116            err = AVERROR(err);                                               \
    117            goto fail;                                                        \
    118        }                                                                     \
    119    }
    120    PTHREAD_INIT_LOOP(mutex)
    121    PTHREAD_INIT_LOOP(cond)
    122 
    123 fail:
    124    *(unsigned*)((char*)obj + offsets[0]) = cnt;
    125    return err;
    126 }