La [biblioteca estándar de hilos de C11](https://en.cppreference.com/w/c/thread) incluye dos mecanismos de control de concurrencia: exclusión mutua (*mutex*) y variables de condición. El siguiente ejemplo hace que los dos hilos secundarios incrementen una variable global sin provocar una condición de carrera:

```c
#include <threads.h>
#include <stdio.h>
#include <stdlib.h>

mtx_t can_access_count;
size_t count = 0;

int increase(void* data) {
  (void)data;
  mtx_lock(&can_access_count);
  ++count;
  mtx_unlock(&can_access_count);
  return EXIT_SUCCESS;
}

int main(void) {
  mtx_init(&can_access_count, mtx_plain);
  thrd_t thread[2];
  thrd_create(&thread[0], increase, (void*)NULL);
  thrd_create(&thread[1], increase, (void*)NULL);
  thrd_join(thread[0], NULL);
  thrd_join(thread[1], NULL);
  printf("count = %zu\n", count);
  mtx_destroy(&can_access_count);
  return EXIT_SUCCESS;
}
```

El tipo de datos `mtx_t` declarado en el encabezado `<threads.h>` define un *mutex*. Antes de usarlo, debe ser inicializado con la función `mtx_init()` que recibe un puntero al mutex y su tipo. Al inicio de `main()` en el código de arriba se creó un mutex de tipo simple (`mtx_plain`). Sin embargo se puede pedir otros tipos de *mutex* con características adicionales, como permitir bloquear el *mutex* por un periodo de tiempo (`mtx_timed`) y permitir bloquear el *mutex* recursivamente (`mtx_recursive`). Una vez que ya no se va a usar más un *mutex*, se debe destruir con `mtx_destroy()`, como se hizo al final del `main()`. Para bloquear (esperar) y desbloquear el *mutex* se usan las funciones `mtx_lock()` y `mtx_unlock()` que reciben la dirección de memoria del *mutex*.

El problema a resolver es el siguiente. El hilo principal se quedó sin dinero y pidió ayuda a sus amigos, los hilos secundarios, quienes decidieron hacer una colecta. En la entrada estándar se indica la cantidad de amigos que tiene el hilo principal y la cantidad de dinero que necesita recolectar, medida en dólares. Al igual que los humanos, no todos los hilos son igual de generosos. Suponga que un hilo está dispuesto a aportar hasta un máximo de `rank + 1` dólares. Por ejemplo, el hilo 0 es el más tacaño de todos y estaría dispuesto a aportar máximo \$1, le sigue el hilo 1 que aportaría máximo \$2, y así sucesivamente.

Al igual que los humanos, no se sabe cuál amigo va a aportar primero ni en qué orden lo harán. Cada vez que un hilo va a hacer su aporte lo hace de la siguiente manera. Primero el hilo revisa cuánto dinero le hace falta a lo ya recolectado para alcanzar el monto que necesita el hilo principal. Luego, el hilo decide cuánto va a aportar, que puede ser lo que hace falta si está dentro de sus posibilidades o su máximo personal. Acto seguido el hilo consigue el dinero, que puede requerir ir al cajero. Para simular este paso haga al hilo dormir por exactamente 1 milisegundo. Una vez que el hilo haya conseguido el efectivo, lo aporta a la colecta global y termina su ejecución. Una vez que todos los hilos secundarios hayan hecho su aporte, el hilo principal imprime la cantidad de dinero que sus amigos le recolectaron. Puede ocurrir que esta cantidad no alcance el monto solicitado por el hilo principal, pero nunca debe sobrepasarla.

*Ejemplo de entrada*

    3 7.5


*Ejemplo de salida*

    6

En el ejemplo anterior el hilo principal solicitó \$7.5 que supera el monto máximo que sus tres amigos están dispuestos a aportar: \$1 + \$2 + \$3 = \$6.

**Nota 1**: Puede crear más variables globales para resolver este problema.

**Nota 2**: A la fecha, ni *Thread Sanitizer* ni *Valgrind* soportan los hilos estándar de C11.

**Nota 3**: Recuerde hacer un *commit* al finalizar el problema, dado que estos son los que se usarán para calificar la tarea.
