forked from enlightenment/efl
184 lines
5.1 KiB
C
184 lines
5.1 KiB
C
/* EINA - EFL data type library
|
|
* Copyright (C) 2016 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 <stdio.h>
|
|
|
|
#include <Eina.h>
|
|
|
|
#include "eina_suite.h"
|
|
|
|
static int test_array[128] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
|
static int test_array2[64] = { 8, 9, 10, 11, 12, 13, 14 };
|
|
static const void *pointers[EINA_C_ARRAY_LENGTH(test_array) + EINA_C_ARRAY_LENGTH(test_array2)] = { NULL };
|
|
|
|
EFL_START_TEST(eina_test_safepointer_reusable)
|
|
{
|
|
unsigned int i;
|
|
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array); i++)
|
|
{
|
|
const void *ptr = pointers[i] = eina_safepointer_register(&test_array[i]);
|
|
ck_assert_ptr_ne(ptr, NULL);
|
|
ck_assert_ptr_ne(ptr, &test_array[i]);
|
|
ck_assert_ptr_eq(&test_array[i], eina_safepointer_get(pointers[i]));
|
|
}
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array2); i++)
|
|
{
|
|
const void *ptr = pointers[i + EINA_C_ARRAY_LENGTH(test_array)] = eina_safepointer_register(&test_array2[i]);
|
|
ck_assert_ptr_ne(ptr, NULL);
|
|
ck_assert_ptr_ne(ptr, &test_array2[i]);
|
|
ck_assert_ptr_eq(&test_array2[i], eina_safepointer_get(ptr));
|
|
eina_safepointer_unregister(ptr);
|
|
}
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array); i++)
|
|
{
|
|
eina_safepointer_unregister(pointers[i]);
|
|
}
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(pointers); i++)
|
|
{
|
|
unsigned int j;
|
|
|
|
for (j = i + 1; j < EINA_C_ARRAY_LENGTH(pointers); j++)
|
|
{
|
|
ck_assert_ptr_ne(pointers[j], pointers[i]);
|
|
}
|
|
}
|
|
|
|
}
|
|
EFL_END_TEST
|
|
|
|
static Eina_Barrier b;
|
|
|
|
static void *
|
|
_thread1(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
|
|
{
|
|
unsigned int i;
|
|
|
|
ck_assert_int_ne(eina_barrier_wait(&b), 0);
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array); i++)
|
|
{
|
|
const void *ptr = pointers[i] = eina_safepointer_register(&test_array[i]);
|
|
ck_assert_ptr_ne(ptr, NULL);
|
|
ck_assert_ptr_ne(ptr, &test_array[i]);
|
|
ck_assert_ptr_eq(&test_array[i], eina_safepointer_get(ptr));
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void *
|
|
_thread2(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
|
|
{
|
|
unsigned int i;
|
|
|
|
ck_assert_int_ne(eina_barrier_wait(&b), 0);
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array2); i++)
|
|
{
|
|
const void *ptr = pointers[i + (EINA_C_ARRAY_LENGTH(test_array))] = eina_safepointer_register(&test_array2[i]);
|
|
ck_assert_ptr_ne(ptr, NULL);
|
|
ck_assert_ptr_ne(ptr, &test_array2[i]);
|
|
ck_assert_ptr_eq(&test_array2[i], eina_safepointer_get(ptr));
|
|
eina_safepointer_unregister(ptr);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EFL_START_TEST(eina_test_safepointer_threading)
|
|
{
|
|
Eina_Thread t1, t2;
|
|
unsigned int i;
|
|
|
|
|
|
// We need a barrier so that both thread are more likely
|
|
// to start running in parallel
|
|
ck_assert_int_ne(eina_barrier_new(&b, 2), 0);
|
|
|
|
// Spawn them
|
|
ck_assert_int_ne(eina_thread_create(&t1, EINA_THREAD_NORMAL, -1, _thread1, NULL), 0);
|
|
ck_assert_int_ne(eina_thread_create(&t2, EINA_THREAD_NORMAL, -1, _thread2, NULL), 0);
|
|
|
|
// And wait for the outcome !
|
|
eina_thread_join(t1);
|
|
eina_thread_join(t2);
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array); i++)
|
|
{
|
|
eina_safepointer_unregister(pointers[i]);
|
|
}
|
|
|
|
eina_barrier_free(&b);
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(pointers); i++)
|
|
{
|
|
unsigned int j;
|
|
|
|
for (j = i + 1; j < EINA_C_ARRAY_LENGTH(pointers); j++)
|
|
{
|
|
ck_assert_ptr_ne(pointers[j], pointers[i]);
|
|
}
|
|
}
|
|
|
|
}
|
|
EFL_END_TEST
|
|
|
|
EFL_START_TEST(eina_test_safepointer_lowestbit)
|
|
{
|
|
unsigned int i;
|
|
|
|
|
|
for (i = 0; i < EINA_C_ARRAY_LENGTH(test_array); i++)
|
|
{
|
|
const void *ptr = eina_safepointer_register(&test_array[i]);
|
|
ck_assert_ptr_ne(ptr, NULL);
|
|
ck_assert_ptr_ne(ptr, &test_array[i]);
|
|
ck_assert_ptr_eq(&test_array[i], eina_safepointer_get(ptr));
|
|
|
|
// We do guarantee that the two lower bit are always zero and will be internally ignored
|
|
ck_assert_int_eq((((uintptr_t) ptr) & 0x3), 0);
|
|
ptr = (void*)(((uintptr_t) ptr) | 0x3);
|
|
|
|
ck_assert_ptr_eq(&test_array[i], eina_safepointer_get(ptr));
|
|
|
|
eina_safepointer_unregister(ptr);
|
|
|
|
EXPECT_ERROR_START;
|
|
ck_assert_ptr_eq(eina_safepointer_get(ptr), NULL);
|
|
EXPECT_ERROR_END;
|
|
}
|
|
}
|
|
EFL_END_TEST
|
|
|
|
void
|
|
eina_test_safepointer(TCase *tc)
|
|
{
|
|
tcase_add_test(tc, eina_test_safepointer_reusable);
|
|
tcase_add_test(tc, eina_test_safepointer_threading);
|
|
tcase_add_test(tc, eina_test_safepointer_lowestbit);
|
|
}
|