Ejemplo n.º 1
0
static
void RunBasicTest()
{
    int value;
    SDL_SpinLock lock = 0;

    SDL_atomic_t v;
    SDL_bool tfret = SDL_FALSE;

    printf("\nspin lock---------------------------------------\n\n");

    SDL_AtomicLock(&lock);
    printf("AtomicLock                   lock=%d\n", lock);
    SDL_AtomicUnlock(&lock);
    printf("AtomicUnlock                 lock=%d\n", lock);

    printf("\natomic -----------------------------------------\n\n");
     
    SDL_AtomicSet(&v, 0);
    tfret = SDL_AtomicSet(&v, 10) == 0;
    printf("AtomicSet(10)        tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
    tfret = SDL_AtomicAdd(&v, 10) == 10;
    printf("AtomicAdd(10)        tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));

    SDL_AtomicSet(&v, 0);
    SDL_AtomicIncRef(&v);
    tfret = (SDL_AtomicGet(&v) == 1);
    printf("AtomicIncRef()       tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
    SDL_AtomicIncRef(&v);
    tfret = (SDL_AtomicGet(&v) == 2);
    printf("AtomicIncRef()       tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
    tfret = (SDL_AtomicDecRef(&v) == SDL_FALSE);
    printf("AtomicDecRef()       tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
    tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE);
    printf("AtomicDecRef()       tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));

    SDL_AtomicSet(&v, 10);
    tfret = (SDL_AtomicCAS(&v, 0, 20) == SDL_FALSE);
    printf("AtomicCAS()          tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
    value = SDL_AtomicGet(&v);
    tfret = (SDL_AtomicCAS(&v, value, 20) == SDL_TRUE);
    printf("AtomicCAS()          tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v));
}
Ejemplo n.º 2
0
/*
 * SDL.createThread(name, source)
 *
 * Create a separate thread of execution. It creates a new Lua state that
 * does not share any data frmo the parent process.
 *
 * Arguments:
 *	name, the thread name
 *	source, a path to a Lua file or a function to call
 *
 * Returns:
 *	The thread object or nil
 *	The error message
 */
static int
l_thread_create(lua_State *L)
{
	const char *name = luaL_checkstring(L, 1);
	int ret, iv;
	LuaThread *thread;

	if ((thread = calloc(1, sizeof (LuaThread))) == NULL)
		return commonPushErrno(L, 1);

	thread->L = luaL_newstate();
	luaL_openlibs(thread->L);

	ret = threadDump(L, thread->L, 2);

	/* If return number is 2, it is nil and the error */
	if (ret == 2)
		goto failure;

	/* Iterate over the arguments to pass to the callback */
	for (iv = 3; iv <= lua_gettop(L); ++iv) {
		Variant *v = variantGet(L, iv);

		if (v == NULL) {
			commonPushErrno(L, 1);
			goto failure;
		}

		variantPush(thread->L, v);
		variantFree(v);
	}

	thread->ptr = SDL_CreateThread((SDL_ThreadFunction)callback, name, thread);
	if (thread->ptr == NULL) {
		commonPushSDLError(L, 1);
		goto failure;
	}

	SDL_AtomicIncRef(&thread->ref);

	return commonPush(L, "p", ThreadName, thread);

failure:
	lua_close(thread->L);
	free(thread);

	return 2;
}
Ejemplo n.º 3
0
static int
callback(LuaThread *t)
{
	int ret = -1;

	SDL_AtomicIncRef(&t->ref);

	if (lua_pcall(t->L, lua_gettop(t->L) - 1, 1, 0) != LUA_OK)
		SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "%s", lua_tostring(t->L, -1));
	else
		ret = lua_tointeger(t->L, -1);

	destroy(t);

	return ret;
}
Ejemplo n.º 4
0
static SDL_bool DequeueEvent_LockFree(SDL_EventQueue *queue, SDL_Event *event)
{
    SDL_EventQueueEntry *entry;
    unsigned queue_pos;
    unsigned entry_seq;
    int delta;
    SDL_bool status;

#ifdef TEST_SPINLOCK_FIFO
    /* This is a gate so an external thread can lock the queue */
    SDL_AtomicLock(&queue->lock);
    SDL_assert(SDL_AtomicGet(&queue->watcher) == 0);
    SDL_AtomicIncRef(&queue->rwcount);
    SDL_AtomicUnlock(&queue->lock);
#endif

    queue_pos = (unsigned)SDL_AtomicGet(&queue->dequeue_pos);
    for ( ; ; ) {
        entry = &queue->entries[queue_pos & WRAP_MASK];
        entry_seq = (unsigned)SDL_AtomicGet(&entry->sequence);

        delta = (int)(entry_seq - (queue_pos + 1));
        if (delta == 0) {
            /* The entry and the queue position match, try to increment the queue position */
            if (SDL_AtomicCAS(&queue->dequeue_pos, (int)queue_pos, (int)(queue_pos+1))) {
                /* We own the object, fill it! */
                *event = entry->event;
                SDL_AtomicSet(&entry->sequence, (int)(queue_pos+MAX_ENTRIES));
                status = SDL_TRUE;
                break;
            }
        } else if (delta < 0) {
            /* We ran into an old queue entry, which means we've hit empty */
            status = SDL_FALSE;
            break;
        } else {
            /* We ran into a new queue entry, get the new queue position */
            queue_pos = (unsigned)SDL_AtomicGet(&queue->dequeue_pos);
        }
    }

#ifdef TEST_SPINLOCK_FIFO
    SDL_AtomicDecRef(&queue->rwcount);
#endif
    return status;
}
Ejemplo n.º 5
0
internal bool32
SDLDoNextWorkQueueEntry(platform_work_queue *Queue) {
    bool32 WeShouldSleep = false;

    int OriginalNextEntryToRead = Queue->NextEntryToRead.value;
    int NewNextEntryToRead = (OriginalNextEntryToRead + 1) % ArrayCount(Queue->Entries);
    if (OriginalNextEntryToRead != Queue->NextEntryToWrite.value) {
        if (SDL_AtomicCAS(&Queue->NextEntryToRead, OriginalNextEntryToRead, NewNextEntryToRead)) {
            platform_work_queue_entry Entry = Queue->Entries[OriginalNextEntryToRead];
            Entry.Callback(Queue, Entry.Data);
            SDL_AtomicIncRef(&Queue->CompletionCount);
        }
    } else {
        WeShouldSleep = true;
    }

    return WeShouldSleep;
}
Ejemplo n.º 6
0
/* This thread periodically locks the queue for no particular reason */
static int FIFO_Watcher(void* _data)
{
    SDL_EventQueue *queue = (SDL_EventQueue *)_data;

    while (queue->active) {
        SDL_AtomicLock(&queue->lock);
        SDL_AtomicIncRef(&queue->watcher);
        while (SDL_AtomicGet(&queue->rwcount) > 0) {
            SDL_Delay(0);
        }
        /* Do queue manipulation here... */
        SDL_AtomicDecRef(&queue->watcher);
        SDL_AtomicUnlock(&queue->lock);

        /* Wait a bit... */
        SDL_Delay(1);
    }
    return 0;
}
Ejemplo n.º 7
0
Task* taskmgr_submit(TaskManager *mgr, TaskParams params) {
	assert(params.callback != NULL);

	Task *task = calloc(1, sizeof(Task));
	task->callback = params.callback;
	task->userdata_free_callback = params.userdata_free_callback;
	task->userdata = params.userdata;
	task->prio = params.prio;
	task->status = TASK_PENDING;

	if(!(task->mutex = SDL_CreateMutex())) {
		log_sdl_error(LOG_WARN, "SDL_CreateMutex");
		goto fail;
	}

	if(!(task->cond = SDL_CreateCond())) {
		log_sdl_error(LOG_WARN, "SDL_CreateCond");
		goto fail;
	}

	SDL_LockMutex(mgr->mutex);

	if(params.topmost) {
		alist_insert_at_priority_head(&mgr->queue, task, task->prio, task_prio_func);
	} else {
		alist_insert_at_priority_tail(&mgr->queue, task, task->prio, task_prio_func);
	}

	task->in_queue = true;
	SDL_AtomicIncRef(&mgr->numtasks);
	SDL_CondSignal(mgr->cond);
	SDL_UnlockMutex(mgr->mutex);

	return task;

fail:
	task_free(task);
	return NULL;
}
Ejemplo n.º 8
0
SDL_TimerID
SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
{
    SDL_TimerData *data = &SDL_timer_data;
    SDL_Timer *timer;
    SDL_TimerMap *entry;

    if (!data->active) {
        int status = 0;

        SDL_AtomicLock(&data->lock);
        if (!data->active) {
            status = SDL_TimerInit();
        }
        SDL_AtomicUnlock(&data->lock);

        if (status < 0) {
            return 0;
        }
    }

    SDL_AtomicLock(&data->lock);
    timer = data->freelist;
    if (timer) {
        data->freelist = timer->next;
    }
    SDL_AtomicUnlock(&data->lock);

    if (timer) {
        SDL_RemoveTimer(timer->timerID);
    } else {
        timer = (SDL_Timer *)SDL_malloc(sizeof(*timer));
        if (!timer) {
            SDL_OutOfMemory();
            return 0;
        }
    }
    timer->timerID = SDL_AtomicIncRef(&data->nextID);
    timer->callback = callback;
    timer->param = param;
    timer->interval = interval;
    timer->scheduled = SDL_GetTicks() + interval;
    timer->canceled = SDL_FALSE;
 
    entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
    if (!entry) {
        SDL_free(timer);
        SDL_OutOfMemory();
        return 0;
    }
    entry->timer = timer;
    entry->timerID = timer->timerID;

    SDL_mutexP(data->timermap_lock);
    entry->next = data->timermap;
    data->timermap = entry;
    SDL_mutexV(data->timermap_lock);

    /* Add the timer to the pending list for the timer thread */
    SDL_AtomicLock(&data->lock);
    timer->next = data->pending;
    data->pending = timer;
    SDL_AtomicUnlock(&data->lock);

    /* Wake up the timer thread if necessary */
    SDL_SemPost(data->sem);

    return entry->timerID;
}
Ejemplo n.º 9
0
 void ref() {
   SDL_AtomicIncRef(&refcnt);
 }
Ejemplo n.º 10
0
SDL_TLSID
SDL_TLSCreate()
{
    static SDL_atomic_t SDL_tls_id;
    return SDL_AtomicIncRef(&SDL_tls_id)+1;
}