#include <stdlib.h>
#include <threads.h>
#include <stdbool.h>
#include "queue.h"
#include <stdio.h>
int metidos=1;
int quitados=1;
// circular array
typedef struct _queue {
int size;
int used;
int first;
void **data;
mtx_t * mutex;
cnd_t * full;
cnd_t * empty;
bool terminado;
} _queue;
void q_terminar(queue q){
printf("Entra en q_terminar\n");
q->terminado=true;
cnd_broadcast(q->empty);
}
queue q_create(int size) {
queue q = malloc(sizeof(_queue));
q->size = size;
q->used = 0;
q->first = 0;
q->data = malloc(size * sizeof(void *));
q->mutex = malloc(sizeof (mtx_t));
q->full = malloc(sizeof(cnd_t));
q->empty = malloc(sizeof(cnd_t));
q->terminado=false;
mtx_init(q->mutex, mtx_plain);
cnd_init(q->full);
cnd_init(q->empty);
return q;
}
int q_elements(queue q) {
mtx_lock(q->mutex);
int res= q->used;
mtx_unlock(q->mutex);
return res;
}
int q_insert(queue q, void *elem) {
if(q->terminado==true){
return 1;
}
printf("Entra en insert\n");
mtx_lock(q->mutex);
while(q->used == q->size){
printf("ESperando para insertar\n");
cnd_wait(q->full, q->mutex);
printf("Recibiendo señal para insertar\n");
}
//if(q->size == q->used) return -1;
q->data[(q->first + q->used) % q->size] = elem;
q->used++;
printf("Insertado, este es el elemento %d en ser insertado\n",metidos);
printf("En la cola hay %d elementos\n",q->used);
metidos++;
if(q->used == 1){
cnd_broadcast(q->empty);
printf("Enviando señal para despertar a los que borran\n");
}
mtx_unlock(q->mutex);
return 0;
}
void *q_remove(queue q) {
printf("Entra en remove\n");
void *res;
mtx_lock(q->mutex);
if(q->terminado == true){
return NULL;
}
while(q->used ==0){
printf("Esperando para quitar\n");
cnd_wait(q->empty, q->mutex);
printf("Recibiendo señal para quitar\n");
}
if(q->used == 0) return NULL;
res = q->data[q->first];
q->first = (q->first + 1) % q->size;
q->used--;
cnd_signal(q->full);
printf("Quitado, este es el elemento %d en ser quitado\n", quitados);
printf("En la cola hay %d elementos\n",q->used);
quitados++;
if(q->used == q->size-1){
cnd_broadcast(q->full);
printf("Enviando señal para despertar a los que insertan\n");
}
mtx_unlock(q->mutex);
return res;
}
void q_destroy(queue q) {
mtx_destroy(q->mutex);
cnd_destroy(q->full);
cnd_destroy(q->empty);
free(q->full);
free(q->empty);
free(q->mutex);
free(q->data);
free(q);
}