Esempio n. 1
0
static void
destroy(LuaThread *t)
{
	(void)SDL_AtomicDecRef(&t->ref);

	if (SDL_AtomicGet(&t->ref) == 0) {
		lua_close(t->L);
		free(t);
	}
}
Esempio n. 2
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));
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
 void unref() {
   if(SDL_AtomicDecRef(&refcnt))
     delete this;
 }
Esempio n. 6
0
static int taskmgr_thread(void *arg) {
	TaskManager *mgr = arg;
	attr_unused SDL_threadID tid = SDL_ThreadID();

	if(SDL_SetThreadPriority(mgr->thread_prio) < 0) {
		log_sdl_error(LOG_WARN, "SDL_SetThreadPriority");
	}

	bool running;
	bool aborted;

	do {
		SDL_LockMutex(mgr->mutex);

		running = mgr->running;
		aborted = mgr->aborted;

		if(!running && !aborted) {
			SDL_CondWait(mgr->cond, mgr->mutex);
		}

		SDL_UnlockMutex(mgr->mutex);
	} while(!running && !aborted);

	while(running && !aborted) {
		SDL_LockMutex(mgr->mutex);
		Task *task = alist_pop(&mgr->queue);

		running = mgr->running;
		aborted = mgr->aborted;

		if(running && task == NULL && !aborted) {
			SDL_CondWait(mgr->cond, mgr->mutex);
		}

		SDL_UnlockMutex(mgr->mutex);

		if(task != NULL) {
			SDL_LockMutex(task->mutex);

			bool task_disowned = task->disowned;

			if(aborted && task->status == TASK_PENDING) {
				task->status = TASK_CANCELLED;
			}

			if(task->status == TASK_PENDING) {
				task->status = TASK_RUNNING;

				SDL_UnlockMutex(task->mutex);
				task->result = task->callback(task->userdata);
				SDL_LockMutex(task->mutex);

				assert(task->in_queue);
				task->in_queue = false;
				(void)SDL_AtomicDecRef(&mgr->numtasks);

				if((task_disowned = task->disowned)) {
					SDL_UnlockMutex(task->mutex);
					task_free(task);
				} else {
					task->status = TASK_FINISHED;
					SDL_CondBroadcast(task->cond);
					SDL_UnlockMutex(task->mutex);
				}
			} else if(task->status == TASK_CANCELLED) {
				assert(task->in_queue);
				task->in_queue = false;
				(void)SDL_AtomicDecRef(&mgr->numtasks);
				SDL_UnlockMutex(task->mutex);

				if(task_disowned) {
					task_free(task);
				}
			} else {
				UNREACHABLE;
			}
		}
	}

	return 0;
}