2013-10-16 00:47:21 -07:00
|
|
|
/* EINA - EFL data type library
|
|
|
|
* Copyright (C) 2013 Cedric Bail
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "eina_suite.h"
|
|
|
|
#include "Eina.h"
|
|
|
|
|
|
|
|
static Eina_Spinlock spin;
|
|
|
|
static Eina_Thread thread;
|
|
|
|
static unsigned int counter;
|
|
|
|
|
|
|
|
static void *
|
|
|
|
_eina_test_lock_thread(void *data, Eina_Thread t)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
fail_if(!eina_thread_equal(t, thread));
|
|
|
|
fail_if(strcmp("test", data));
|
|
|
|
|
|
|
|
for (i = 0; i < 10000; i++)
|
|
|
|
{
|
|
|
|
fail_if(eina_spinlock_take(&spin) != EINA_LOCK_SUCCEED);
|
|
|
|
counter++;
|
|
|
|
fail_if(eina_spinlock_release(&spin) != EINA_LOCK_SUCCEED);
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
START_TEST(eina_test_spinlock)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
fail_if(!eina_init());
|
|
|
|
|
|
|
|
counter = 0;
|
|
|
|
fail_if(!eina_spinlock_new(&spin));
|
|
|
|
|
|
|
|
fail_if(!eina_thread_create(&thread, EINA_THREAD_NORMAL, 0, _eina_test_lock_thread, "test"));
|
|
|
|
|
|
|
|
for (i = 0; i < 10000; i++)
|
|
|
|
{
|
|
|
|
fail_if(eina_spinlock_take(&spin) != EINA_LOCK_SUCCEED);
|
|
|
|
counter++;
|
|
|
|
fail_if(eina_spinlock_release(&spin) != EINA_LOCK_SUCCEED);
|
|
|
|
}
|
|
|
|
|
|
|
|
fail_if(strcmp("test", eina_thread_join(thread)));
|
|
|
|
|
|
|
|
fail_if(counter != 20000);
|
|
|
|
|
2013-10-24 23:12:28 -07:00
|
|
|
fail_if(eina_spinlock_take_try(&spin) != EINA_LOCK_SUCCEED);
|
|
|
|
fail_if(eina_spinlock_release(&spin) != EINA_LOCK_SUCCEED);
|
|
|
|
|
2013-10-16 00:47:21 -07:00
|
|
|
eina_spinlock_free(&spin);
|
|
|
|
|
|
|
|
eina_shutdown();
|
|
|
|
}
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
static Eina_TLS key;
|
2014-01-22 21:50:08 -08:00
|
|
|
static int _eina_tls_free_count = 0;
|
|
|
|
|
|
|
|
static void *
|
|
|
|
_eina_test_tls_alloc(int v)
|
|
|
|
{
|
|
|
|
int *ptr = malloc(sizeof(int));
|
|
|
|
*ptr = v;
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eina_test_tls_free(void *ptr)
|
|
|
|
{
|
|
|
|
_eina_tls_free_count++;
|
|
|
|
free(ptr);
|
|
|
|
}
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
static void *
|
|
|
|
_eina_test_tls_thread(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
|
|
|
|
{
|
2014-01-22 21:50:08 -08:00
|
|
|
int *ptr;
|
|
|
|
|
|
|
|
ptr = eina_tls_get(key);
|
|
|
|
fail_if(eina_tls_get(key) != NULL);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
2014-01-22 21:50:08 -08:00
|
|
|
fail_if(!eina_tls_set(key, _eina_test_tls_alloc(24)));
|
|
|
|
|
|
|
|
ptr = eina_tls_get(key);
|
|
|
|
fail_if(eina_tls_get(key) == NULL);
|
|
|
|
fail_if(*ptr != 24);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
START_TEST(eina_test_tls)
|
|
|
|
{
|
|
|
|
fail_if(!eina_init());
|
|
|
|
|
2014-01-22 21:50:08 -08:00
|
|
|
fail_if(!eina_tls_cb_new(&key, _eina_test_tls_free));
|
2013-10-16 00:47:21 -07:00
|
|
|
|
2014-01-22 21:50:08 -08:00
|
|
|
fail_if(!eina_tls_set(key, _eina_test_tls_alloc(42)));
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
fail_if(!eina_thread_create(&thread, EINA_THREAD_NORMAL, 0, _eina_test_tls_thread, NULL));
|
|
|
|
|
|
|
|
eina_thread_join(thread);
|
2014-01-22 21:50:08 -08:00
|
|
|
fail_if(_eina_tls_free_count != 1);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
2014-01-22 21:50:08 -08:00
|
|
|
int *ptr = eina_tls_get(key);
|
|
|
|
fail_if(eina_tls_get(key) == NULL);
|
|
|
|
fail_if(*ptr != 42);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
eina_tls_free(key);
|
|
|
|
|
|
|
|
eina_shutdown();
|
|
|
|
}
|
|
|
|
END_TEST
|
|
|
|
|
2013-10-24 23:12:28 -07:00
|
|
|
static Eina_Barrier barrier;
|
2013-10-16 00:47:21 -07:00
|
|
|
static Eina_Lock mtcond;
|
|
|
|
static Eina_Condition cond;
|
|
|
|
static Eina_RWLock mutex;
|
|
|
|
|
|
|
|
static void *
|
|
|
|
_eina_test_rwlock_thread(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
|
|
|
|
{
|
2013-10-24 23:12:28 -07:00
|
|
|
fail_if(!eina_barrier_wait(&barrier));
|
|
|
|
fail_if(eina_lock_take(&mtcond) != EINA_LOCK_SUCCEED);
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(!eina_condition_broadcast(&cond));
|
2013-10-24 23:12:28 -07:00
|
|
|
fail_if(eina_lock_release(&mtcond) != EINA_LOCK_SUCCEED);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
fail_if(eina_rwlock_take_write(&mutex) != EINA_LOCK_SUCCEED);
|
|
|
|
counter = 7200;
|
|
|
|
fail_if(eina_rwlock_release(&mutex) != EINA_LOCK_SUCCEED);
|
|
|
|
|
2014-01-23 19:00:32 -08:00
|
|
|
fail_if(!eina_barrier_wait(&barrier));
|
|
|
|
|
|
|
|
fail_if(eina_lock_take(&mtcond) != EINA_LOCK_SUCCEED);
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(!eina_condition_broadcast(&cond));
|
2014-01-23 19:00:32 -08:00
|
|
|
fail_if(eina_lock_release(&mtcond) != EINA_LOCK_SUCCEED);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
START_TEST(eina_test_rwlock)
|
|
|
|
{
|
2014-10-30 04:09:43 -07:00
|
|
|
struct timespec ts, ts2;
|
|
|
|
long delay;
|
|
|
|
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(!eina_init());
|
|
|
|
|
|
|
|
fail_if(!eina_rwlock_new(&mutex));
|
|
|
|
fail_if(!eina_lock_new(&mtcond));
|
|
|
|
fail_if(!eina_condition_new(&cond, &mtcond));
|
2013-10-24 23:12:28 -07:00
|
|
|
fail_if(!eina_barrier_new(&barrier, 2));
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
counter = 42;
|
|
|
|
|
2013-11-09 03:06:59 -08:00
|
|
|
eina_lock_debug(&mtcond);
|
2013-10-24 23:12:28 -07:00
|
|
|
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(eina_rwlock_take_read(&mutex) != EINA_LOCK_SUCCEED);
|
|
|
|
fail_if(eina_lock_take(&mtcond) != EINA_LOCK_SUCCEED);
|
|
|
|
|
|
|
|
fail_if(!eina_thread_create(&thread, EINA_THREAD_NORMAL, 0, _eina_test_rwlock_thread, NULL));
|
|
|
|
|
2013-10-24 23:12:28 -07:00
|
|
|
fail_if(!eina_barrier_wait(&barrier));
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(!eina_condition_wait(&cond));
|
2013-10-24 23:12:28 -07:00
|
|
|
fail_if(eina_lock_release(&mtcond) != EINA_LOCK_SUCCEED);
|
2013-10-16 00:47:21 -07:00
|
|
|
|
|
|
|
fail_if(counter != 42);
|
|
|
|
fail_if(eina_rwlock_release(&mutex) != EINA_LOCK_SUCCEED);
|
|
|
|
|
|
|
|
fail_if(eina_lock_take(&mtcond) != EINA_LOCK_SUCCEED);
|
2014-01-23 19:00:32 -08:00
|
|
|
fail_if(!eina_barrier_wait(&barrier));
|
|
|
|
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(!eina_condition_wait(&cond));
|
|
|
|
fail_if(eina_lock_release(&mtcond) != EINA_LOCK_SUCCEED);
|
2014-01-23 19:00:32 -08:00
|
|
|
|
2013-10-16 00:47:21 -07:00
|
|
|
fail_if(eina_rwlock_take_read(&mutex) != EINA_LOCK_SUCCEED);
|
|
|
|
fail_if(counter != 7200);
|
|
|
|
fail_if(eina_rwlock_release(&mutex) != EINA_LOCK_SUCCEED);
|
|
|
|
|
2014-10-30 04:09:43 -07:00
|
|
|
#ifndef _WIN32
|
|
|
|
fail_if(eina_lock_take(&mtcond) != EINA_LOCK_SUCCEED);
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
|
eina_condition_timedwait(&cond, 0.050);
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts2);
|
|
|
|
delay = (ts2.tv_sec - ts.tv_sec) * 1000L + (ts2.tv_nsec - ts.tv_nsec) / 1000000L;
|
|
|
|
fail_if(delay < 50);
|
|
|
|
fail_if(delay > 200);
|
|
|
|
fail_if(eina_lock_release(&mtcond) != EINA_LOCK_SUCCEED);
|
|
|
|
#endif
|
|
|
|
|
2013-10-24 23:12:28 -07:00
|
|
|
eina_thread_join(thread);
|
|
|
|
|
2013-10-16 00:47:21 -07:00
|
|
|
eina_condition_free(&cond);
|
|
|
|
eina_lock_free(&mtcond);
|
|
|
|
eina_rwlock_free(&mutex);
|
|
|
|
|
|
|
|
eina_shutdown();
|
|
|
|
}
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
void
|
|
|
|
eina_test_locking(TCase *tc)
|
|
|
|
{
|
|
|
|
tcase_add_test(tc, eina_test_spinlock);
|
|
|
|
tcase_add_test(tc, eina_test_tls);
|
|
|
|
tcase_add_test(tc, eina_test_rwlock);
|
|
|
|
}
|