raytracer-c/module_raytracer/sequences.c
2023-12-10 02:10:20 -05:00

64 lines
1.6 KiB
C

#include "sequences.h"
#include <assert.h>
#include <exceptions.h>
#include <stdlib.h>
#include <string.h>
#include <utilities.h>
#include <pthread.h>
typedef struct SEQUENCES_Sequence {
unsigned int count;
pthread_key_t tl_next_ndx;
double seq[];
} SEQUENCES_Sequence;
SEQUENCES_Sequence *SEQUENCES_new(unsigned int count, double numbers[]) {
assert(count > 0);
SEQUENCES_Sequence *seq = malloc(sizeof(SEQUENCES_Sequence) + count * sizeof(numbers[0]));
if (!seq) {
Throw(E_MALLOC_FAILED);
}
seq->count = count;
memcpy(seq->seq, numbers, count * sizeof(numbers[0]));
pthread_key_create(&seq->tl_next_ndx, free);
return seq;
}
void SEQUENCES_delete(SEQUENCES_Sequence *sequence) {
assert(sequence);
/* TODO: Is this needed? */
size_t* ndx = pthread_getspecific(sequence->tl_next_ndx);
if (ndx) {
free(ndx);
}
pthread_key_delete(sequence->tl_next_ndx);
free(sequence);
}
double SEQUENCES_next(SEQUENCES_Sequence *sequence) {
assert(sequence);
size_t* ndx = pthread_getspecific(sequence->tl_next_ndx);
if (!ndx) {
ndx = calloc(1, sizeof(size_t));
pthread_setspecific(sequence->tl_next_ndx, ndx);
}
double val = sequence->seq[*ndx];
*ndx = (*ndx + 1) % sequence->count;
return val;
}
SEQUENCES_Sequence *SEQUENCES_copy(SEQUENCES_Sequence *sequence) {
SEQUENCES_Sequence *seq = SEQUENCES_new(sequence->count, sequence->seq);
return seq;
}
SEQUENCES_Sequence *SEQUENCES_new_random(unsigned int count) {
assert(count >= 1);
double rands[count];
for (unsigned int ndx = 0; ndx < count; ndx++) {
rands[ndx] = UTILITIES_random_double(0, 1);
}
return SEQUENCES_new(count, rands);
}