Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cute_sync SDL implementation has intermittent segfaults #313

Open
aganm opened this issue Jun 6, 2022 · 2 comments
Open

cute_sync SDL implementation has intermittent segfaults #313

aganm opened this issue Jun 6, 2022 · 2 comments

Comments

@aganm
Copy link
Contributor

aganm commented Jun 6, 2022

I have an issue with cute_threadpool_kick_and_wait resulting in intermittent segfaults when using the SDL implementation.

I allocate memory then I pass this memory to the task function to do some async computation with cute_threadpool_add_task. Then, I call cute_threadpool_kick_and_wait expecting the function to wait and join on all the added tasks to free all my memory. But when I do free all my memory, I get a segfault in the task function for accessing freed memory, meaning the task function is still running after calling cute_threadpool_kick_and_wait.

Am I misunderstanding what this function does? I'm expecting it to block the thread I am calling it from and wait until all the tasks are completed.

This is the code to reproduce:

#include <SDL.h>
#define CUTE_SYNC_IMPLEMENTATION
#define CUTE_SYNC_SDL
#include "cute_sync.h"
#include <stdio.h>
#include <stdlib.h>

typedef struct int_buffer {
	int count;
	int* ptr;
} int_buffer;

void job(void* userdata)
{
	int_buffer* ints = userdata;
	int count = ints->count;
	for (int i = 0; i < count; ++i) {
		ints->ptr[i] = i * count * 30;
	}
}

#define NUM 10

int main()
{
	const int count = 1000000;

	int_buffer ints[NUM];
	for (int i = 0; i < NUM; ++i) {
		ints[i].count = count;
		ints[i].ptr = malloc(sizeof(int) * count);
	}

	cute_threadpool_t* pool = cute_threadpool_create(11, NULL);

	for (int i = 0; i < NUM; ++i) {
		cute_threadpool_add_task(pool, job, &ints[i]);
	}

	/* wait for completion before freeing the memory */
	cute_threadpool_kick_and_wait(pool);

	for (int i = 0; i < NUM; ++i) {
		free(ints[i].ptr);
	}

	cute_threadpool_destroy(pool);

	return 0;
}
cc main.c -lSDL2 -I/usr/include/SDL2

If I run this code 10 times it will segfault about half of the time.

It doesn't segfault if I use the POSIX implementation making me think it's something specific to the SDL implementation.

@iamwhosiam
Copy link

This is 2 years old, you've probably already figured this out, but I had the same issue and I think I have figured it out. I believe the issue is that cute_threadpool_kick_and_wait() exits when all tasks are "started" and not when there finished. So when it exits the last couple of tasks are still being executed.

My hack solution is to have a boolean attached to each task that I set to true after the work is done and just check for that after the _kick_and_wait() but it would be nice if this was the way that the function worked in the first place.

@RandyGaul
Copy link
Owner

Hey awesome! I haven’t used this code for some time — if you have a PR that would be really cool :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants