multithreading work (need to make better)
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
#include "game_core.h"
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const int directions[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1},
|
||||
@@ -73,3 +75,57 @@ Board process_game(Board board) {
|
||||
board.pixels = tmp;
|
||||
return board;
|
||||
}
|
||||
|
||||
void* process_chunk(void* arg) {
|
||||
ThreadArgs* ta = (ThreadArgs*)arg;
|
||||
Board board = (*ta[0].board);
|
||||
size_t x, y;
|
||||
uint8_t count = 0;
|
||||
for (y = ta->y_start; y < ta->y_end; y++) {
|
||||
for (x = 0; x < board.width; x++) {
|
||||
count = count_adjacent(board, x, y);
|
||||
if (board.pixels[y * board.width + x] == BLACK && count == 3) {
|
||||
board.next_pixels[y * board.width + x] = WHITE;
|
||||
} else if (board.pixels[y * board.width + x] == WHITE &&
|
||||
count != 2 && count != 3) {
|
||||
board.next_pixels[y * board.width + x] = BLACK;
|
||||
} else {
|
||||
board.next_pixels[y * board.width + x] =
|
||||
board.pixels[y * board.width + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ThreadArgs* make_chunk(Board* board, size_t n_threads) {
|
||||
size_t i;
|
||||
size_t chunk = board->height / n_threads;
|
||||
ThreadArgs* output = malloc(sizeof(ThreadArgs) * n_threads);
|
||||
for (i = 0; i < n_threads; i++) {
|
||||
output[i].board = board;
|
||||
output[i].y_start = i * chunk;
|
||||
output[i].y_end =
|
||||
(i == n_threads - 1) ? board->height : (i + 1) * chunk;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
Board process_game_mt(ThreadArgs* ta,
|
||||
Board board,
|
||||
pthread_t* threads,
|
||||
size_t n_threads) {
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < n_threads; i++) {
|
||||
ta[i].board = &board;
|
||||
pthread_create(&threads[i], NULL, process_chunk, &ta[i]);
|
||||
}
|
||||
for (i = 0; i < n_threads; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
uint32_t* tmp = board.next_pixels;
|
||||
board.next_pixels = board.pixels;
|
||||
board.pixels = tmp;
|
||||
return board;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,22 @@ typedef struct {
|
||||
size_t height;
|
||||
} Board;
|
||||
|
||||
typedef struct {
|
||||
Board* board;
|
||||
size_t y_start;
|
||||
size_t y_end;
|
||||
} ThreadArgs;
|
||||
|
||||
void free_board(Board board);
|
||||
Board init_board(size_t width, size_t height, int random);
|
||||
int count_adjacent(Board board, size_t x, size_t y);
|
||||
ThreadArgs* make_chunk(Board* board, size_t n_threads);
|
||||
Board process_game(Board board);
|
||||
Board process_game_mt(ThreadArgs* ta,
|
||||
Board board,
|
||||
pthread_t* threads,
|
||||
size_t n_threads);
|
||||
void display_board(Board board);
|
||||
void* process_chunk(void* ta);
|
||||
|
||||
#endif
|
||||
|
||||
76
src/main.c
76
src/main.c
@@ -1,17 +1,24 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_keycode.h>
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <SDL2/SDL_timer.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "game_core.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define SEED (5)
|
||||
#define WIDTH (800)
|
||||
#define HEIGHT (600)
|
||||
#define SIM_WIDTH (800)
|
||||
#define SIM_HEIGHT (600)
|
||||
#define SIM_WIDTH (80)
|
||||
#define SIM_HEIGHT (60)
|
||||
|
||||
const int FPS = 15;
|
||||
const int FRAME_DELAY = 1000 / FPS;
|
||||
|
||||
t_flags process_args(int argc, char** argv) {
|
||||
t_flags output_flags = {0};
|
||||
@@ -36,54 +43,83 @@ t_flags process_args(int argc, char** argv) {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
pthread_t* threads;
|
||||
int n_threads = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
size_t n_chunk;
|
||||
ThreadArgs* ta;
|
||||
t_flags flags = process_args(argc, argv);
|
||||
printf("G : %d , M : %d (n : %d)\n", flags.graphical, flags.multithread,
|
||||
n_threads);
|
||||
srand(time(NULL));
|
||||
|
||||
if (flags.graphical) {
|
||||
Board b = init_board(SIM_WIDTH, SIM_HEIGHT, 0);
|
||||
Board b = init_board(SIM_WIDTH, SIM_HEIGHT, 1);
|
||||
b.pixels[0 * SIM_WIDTH + 1] = WHITE;
|
||||
b.pixels[1 * SIM_WIDTH + 2] = WHITE;
|
||||
b.pixels[2 * SIM_WIDTH + 0] = WHITE;
|
||||
b.pixels[2 * SIM_WIDTH + 1] = WHITE;
|
||||
b.pixels[2 * SIM_WIDTH + 2] = WHITE;
|
||||
if (flags.multithread) {
|
||||
ta = make_chunk(&b, (int)n_threads);
|
||||
threads = malloc(sizeof(pthread_t) * n_threads);
|
||||
n_chunk = b.height / n_threads;
|
||||
}
|
||||
|
||||
// SDL2
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_Window* win = SDL_CreateWindow("pixels", 0, 0, WIDTH, HEIGHT, 0);
|
||||
SDL_Renderer* ren =
|
||||
SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
SDL_Texture* tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
SIM_WIDTH, SIM_HEIGHT);
|
||||
|
||||
int running = 1;
|
||||
SDL_Event e;
|
||||
int pitch;
|
||||
void* tex_pixels;
|
||||
|
||||
// While running frames
|
||||
int running = 1;
|
||||
int paused = 0;
|
||||
int next_frame = 0;
|
||||
Uint32 frame_start;
|
||||
Uint32 frame_time;
|
||||
SDL_Rect dst = {0, 0, WIDTH, HEIGHT};
|
||||
while (running) {
|
||||
while (SDL_PollEvent(&e))
|
||||
frame_start = SDL_GetTicks();
|
||||
if (next_frame)
|
||||
next_frame = 0;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
if (e.type == SDL_QUIT)
|
||||
running = 0;
|
||||
if (e.type == SDL_KEYDOWN) {
|
||||
if (e.key.keysym.sym == SDLK_SPACE)
|
||||
paused = !paused;
|
||||
if (e.key.keysym.sym == SDLK_RIGHT)
|
||||
next_frame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect dst = {0, 0, WIDTH, HEIGHT};
|
||||
SDL_LockTexture(tex, NULL, &tex_pixels, &pitch);
|
||||
memcpy(tex_pixels, b.pixels,
|
||||
SIM_WIDTH * SIM_HEIGHT * sizeof(uint32_t));
|
||||
SDL_UnlockTexture(tex);
|
||||
// SDL_UpdateTexture(tex, NULL, b.pixels,SIM_WIDTH *
|
||||
// sizeof(uint32_t));
|
||||
// SDL_RenderClear(ren);
|
||||
SDL_RenderCopy(ren, tex, NULL, &dst);
|
||||
SDL_RenderPresent(ren);
|
||||
b = process_game(b);
|
||||
// SDL_Delay(100);
|
||||
if (!paused || next_frame) {
|
||||
SDL_LockTexture(tex, NULL, &tex_pixels, &pitch);
|
||||
memcpy(tex_pixels, b.pixels,
|
||||
SIM_WIDTH * SIM_HEIGHT * sizeof(uint32_t));
|
||||
SDL_UnlockTexture(tex);
|
||||
SDL_RenderCopy(ren, tex, NULL, &dst);
|
||||
SDL_RenderPresent(ren);
|
||||
b = !flags.multithread
|
||||
? process_game(b)
|
||||
: process_game_mt(ta, b, threads, n_threads);
|
||||
}
|
||||
frame_time = SDL_GetTicks() - frame_start;
|
||||
if (frame_time < FRAME_DELAY)
|
||||
SDL_Delay(FRAME_DELAY - frame_time);
|
||||
}
|
||||
SDL_DestroyTexture(tex);
|
||||
SDL_DestroyRenderer(ren);
|
||||
SDL_DestroyWindow(win);
|
||||
SDL_Quit();
|
||||
free_board(b);
|
||||
free(threads);
|
||||
|
||||
} else {
|
||||
Board b = init_board(SIM_WIDTH, SIM_HEIGHT, 1);
|
||||
|
||||
Reference in New Issue
Block a user