LCOV - code coverage report
Current view: top level - src/unix - uxthread.c (source / functions) Hit Total Coverage
Test: allegro_auto.info Lines: 38 50 76.0 %
Date: 2018-08-11 00:50:28 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*         ______   ___    ___
       2             :  *        /\  _  \ /\_ \  /\_ \
       3             :  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
       4             :  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
       5             :  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
       6             :  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
       7             :  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
       8             :  *                                           /\____/
       9             :  *                                           \_/__/
      10             :  *
      11             :  *      Internal cross-platform threading API for Unix.
      12             :  *
      13             :  *      By Peter Wang.
      14             :  *
      15             :  *      See readme.txt for copyright information.
      16             :  */
      17             : 
      18             : 
      19             : #define _XOPEN_SOURCE 500       /* for Unix98 recursive mutexes */
      20             :                                 /* XXX: added configure test */
      21             : 
      22             : #include <sys/time.h>
      23             : 
      24             : #include "allegro5/allegro.h"
      25             : #include "allegro5/internal/aintern.h"
      26             : #include "allegro5/internal/aintern_thread.h"
      27             : #include "allegro5/platform/aintunix.h"
      28             : 
      29             : #ifdef ALLEGRO_ANDROID
      30             : #include "allegro5/internal/aintern_android.h"
      31             : #endif
      32             : 
      33             : 
      34             : 
      35             : /* threads */
      36             : 
      37           6 : static void *thread_proc_trampoline(void *data)
      38             : {
      39           6 :    _AL_THREAD *thread = data;
      40             :    /* Android is special and needs to attach/detach threads with Java */
      41             : #ifdef ALLEGRO_ANDROID
      42             :    _al_android_thread_created();
      43             : #endif
      44           6 :    (*thread->proc)(thread, thread->arg);
      45             : #ifdef ALLEGRO_ANDROID
      46             :    _al_android_thread_ended();
      47             : #endif
      48           6 :    return NULL;
      49             : }
      50             : 
      51             : 
      52           6 : void _al_thread_create(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), void *arg)
      53             : {
      54             :    ASSERT(thread);
      55             :    ASSERT(proc);
      56             :    {
      57             :       int status;
      58             : 
      59           6 :       pthread_mutex_init(&thread->mutex, NULL);
      60             : 
      61           6 :       thread->should_stop = false;
      62           6 :       thread->proc = proc;
      63           6 :       thread->arg = arg;
      64             : 
      65           6 :       status = pthread_create(&thread->thread, NULL, thread_proc_trampoline, thread);
      66             :       ASSERT(status == 0);
      67           6 :       if (status != 0)
      68           0 :          abort();
      69             :    }
      70           6 : }
      71             : 
      72             : 
      73           6 : void _al_thread_set_should_stop(_AL_THREAD *thread)
      74             : {
      75             :    ASSERT(thread);
      76             : 
      77           6 :    pthread_mutex_lock(&thread->mutex);
      78             :    {
      79           6 :       thread->should_stop = true;
      80             :    }
      81           6 :    pthread_mutex_unlock(&thread->mutex);
      82           6 : }
      83             : 
      84             : 
      85             : 
      86           6 : void _al_thread_join(_AL_THREAD *thread)
      87             : {
      88             :    ASSERT(thread);
      89             : 
      90           6 :    _al_thread_set_should_stop(thread);
      91           6 :    pthread_join(thread->thread, NULL);
      92             : 
      93           6 :    pthread_mutex_destroy(&thread->mutex);
      94           6 : }
      95             : 
      96             : 
      97           0 : void _al_thread_detach(_AL_THREAD *thread)
      98             : {
      99             :    ASSERT(thread);
     100           0 :    pthread_mutex_destroy(&thread->mutex);
     101           0 :    pthread_detach(thread->thread);
     102           0 : }
     103             : 
     104             : 
     105             : /* mutexes */
     106             : 
     107          31 : void _al_mutex_init(_AL_MUTEX *mutex)
     108             : {
     109             :    ASSERT(mutex);
     110             :     
     111          31 :    pthread_mutex_init(&mutex->mutex, NULL);
     112          31 :    mutex->inited = true;
     113          31 : }
     114             : 
     115             : 
     116          12 : void _al_mutex_init_recursive(_AL_MUTEX *mutex)
     117             : {
     118             :    pthread_mutexattr_t attr;
     119             : 
     120             :    ASSERT(mutex);
     121             : 
     122          12 :    pthread_mutexattr_init(&attr);
     123          12 :    if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EINVAL) {
     124           0 :       pthread_mutexattr_destroy(&attr);
     125           0 :       abort(); /* XXX */
     126             :    }
     127             : 
     128          12 :    pthread_mutex_init(&mutex->mutex, &attr);
     129          12 :    mutex->inited = true;
     130             : 
     131          12 :    pthread_mutexattr_destroy(&attr);
     132          12 : }
     133             : 
     134             : 
     135          34 : void _al_mutex_destroy(_AL_MUTEX *mutex)
     136             : {
     137             :    ASSERT(mutex);
     138             : 
     139          34 :    if (mutex->inited) {
     140          34 :       pthread_mutex_destroy(&mutex->mutex);
     141          34 :       mutex->inited = false;
     142             :    }
     143          34 : }
     144             : 
     145             : 
     146             : /* condition variables */
     147             : /* most of the condition variable implementation is actually inline */
     148             : 
     149           0 : int _al_cond_timedwait(_AL_COND *cond, _AL_MUTEX *mutex,
     150             :    const ALLEGRO_TIMEOUT *timeout)
     151             : {
     152           0 :    ALLEGRO_TIMEOUT_UNIX *unix_timeout = (ALLEGRO_TIMEOUT_UNIX *) timeout;
     153             :    int retcode;
     154             : 
     155           0 :    retcode = pthread_cond_timedwait(&cond->cond, &mutex->mutex,
     156           0 :       &unix_timeout->abstime);
     157             : 
     158           0 :    return (retcode == ETIMEDOUT) ? -1 : 0;
     159             : }
     160             : 
     161             : 
     162             : /*
     163             :  * Local Variables:
     164             :  * c-basic-offset: 3
     165             :  * indent-tabs-mode: nil
     166             :  * End:
     167             :  */

Generated by: LCOV version 1.13