diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c5bd248caca03ceec5d7702cf1b6b3332dccf2c9
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+all: prefixSumPth-v1
+ 
+prefixSumPth-v1: prefixSumPth-v1.c chrono.c
+#	g++ -mcmodel=large prefixSumPth.c -O3 -o prefixSumPth -lpthread
+	g++ prefixSumPth-v1.c -O3 -o prefixSumPth-v1 -lpthread	
+
+
+
diff --git a/Planilha-prefixSum-Pthreads-v1-e-v0-WZ.ods b/Planilha-prefixSum-Pthreads-v1-e-v0-WZ.ods
new file mode 100644
index 0000000000000000000000000000000000000000..215a3eac59313605cb56e99fa44226f291799e87
Binary files /dev/null and b/Planilha-prefixSum-Pthreads-v1-e-v0-WZ.ods differ
diff --git a/README.md b/README.md
index 9467a3f46a656c64f0365716c7c16e30cf29e249..2d68553d05b0f7bcfda9ad38f8e5d97f054696f4 100644
--- a/README.md
+++ b/README.md
@@ -2,91 +2,9 @@
 
 
 
-## Getting started
+## Como rodar
 
-To make it easy for you to get started with GitLab, here's a list of recommended next steps.
+Execute o comando make
 
-Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
+execute com: ./prefixSumPth-v1 <nTotalElements> <nThreads>
 
-## Add your files
-
-- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
-- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
-
-```
-cd existing_repo
-git remote add origin https://gitlab.c3sl.ufpr.br/erb19/parallel-prefix-sum.git
-git branch -M main
-git push -uf origin main
-```
-
-## Integrate with your tools
-
-- [ ] [Set up project integrations](https://gitlab.c3sl.ufpr.br/erb19/parallel-prefix-sum/-/settings/integrations)
-
-## Collaborate with your team
-
-- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
-- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
-- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
-- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
-- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
-
-## Test and Deploy
-
-Use the built-in continuous integration in GitLab.
-
-- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
-- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
-- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
-- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
-- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
-
-***
-
-# Editing this README
-
-When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!).  Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
-
-## Suggestions for a good README
-Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
-
-## Name
-Choose a self-explaining name for your project.
-
-## Description
-Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
-
-## Badges
-On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
-
-## Visuals
-Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
-
-## Installation
-Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
-
-## Usage
-Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
-
-## Support
-Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
-
-## Roadmap
-If you have ideas for releases in the future, it is a good idea to list them in the README.
-
-## Contributing
-State if you are open to contributions and what your requirements are for accepting them.
-
-For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
-
-You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
-
-## Authors and acknowledgment
-Show your appreciation to those who have contributed to the project.
-
-## License
-For open source projects, say how it is licensed.
-
-## Project status
-If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
diff --git a/chrono.c b/chrono.c
new file mode 100644
index 0000000000000000000000000000000000000000..3aa91d60fdad950a0b6786ca9d5df88e0fc0f670
--- /dev/null
+++ b/chrono.c
@@ -0,0 +1,80 @@
+// chrono.h
+//
+// A small library to measure time in programs
+//
+// by W.Zola (2017)
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <sys/time.h>     /* struct timeval definition           */
+#include <unistd.h>       /* declaration of gettimeofday()       */
+
+#include <time.h>
+
+
+  typedef struct {
+
+     struct timespec xadd_time1, xadd_time2;
+     long long xtotal_ns;
+     long xn_events;
+    
+  } chronometer_t;
+ 
+
+  void chrono_reset( chronometer_t *chrono )
+  {
+      chrono->xtotal_ns = 0;
+      chrono->xn_events = 0;
+  }
+
+  inline void chrono_start( chronometer_t *chrono ) {
+      clock_gettime(CLOCK_MONOTONIC_RAW, &(chrono->xadd_time1) );
+  }
+
+  inline long long  chrono_gettotal( chronometer_t *chrono ) {
+      return chrono->xtotal_ns;
+  }
+
+  inline long long  chrono_getcount( chronometer_t *chrono ) {
+      return chrono->xn_events;
+  }
+
+  inline void chrono_stop( chronometer_t *chrono ) {
+
+      clock_gettime(CLOCK_MONOTONIC_RAW, &(chrono->xadd_time2) );
+  
+      long long ns1 = chrono->xadd_time1.tv_sec*1000*1000*1000 + 
+                      chrono->xadd_time1.tv_nsec;
+      long long ns2 = chrono->xadd_time2.tv_sec*1000*1000*1000 + 
+                      chrono->xadd_time2.tv_nsec;
+      long long deltat_ns = ns2 - ns1;
+      
+      chrono->xtotal_ns += deltat_ns;
+      chrono->xn_events++;
+  }
+
+  void chrono_reportTime( chronometer_t *chrono, const char *s ) {
+    
+    printf("\n%s deltaT(ns): %lld ns for %ld ops \n"
+                                              "        ==> each op takes %lld ns\n",
+                  s, chrono->xtotal_ns, chrono->xn_events, 
+                                                chrono->xtotal_ns/chrono->xn_events );
+  }
+
+  void chrono_report_TimeInLoop( chronometer_t *chrono, char *s, int loop_count ) {
+    
+    printf("\n%s deltaT(ns): %lld ns for %ld ops \n"
+                                              "        ==> each op takes %lld ns\n",
+                  s, chrono->xtotal_ns, chrono->xn_events*loop_count, 
+                                  chrono->xtotal_ns/(chrono->xn_events*loop_count) );
+  }
diff --git a/especificacao-do-trabalho1-v1.1.txt b/especificacao-do-trabalho1-v1.1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2b8db2e93c5f0b808ea03515b4b413eb9ce3d9f7
--- /dev/null
+++ b/especificacao-do-trabalho1-v1.1.txt
@@ -0,0 +1,184 @@
+ci1316/ci316  - PROGRAMAÇÃO PARALELA - 
+1o semestre de 2023    
+por W.Zola/UFPR
+
+Lab 1: SomaDePrefixos-com-PThreads   (versão 1.1)  
+----------------------------------
+Histórico:
+- v1.0 a versão inicial
+- v1.1 trocamos para 5milhoes de elementos
+  
+Data do enunciado: 10/maio/2023
+Data da entrega Lab1: 22/maio/2023 (será aproximadamente 2semanas aprox.!)
+
+
+------- PASSOS PARA FAZER ESSE TRABALHO: -----------
+O professor vai fornecer: 
+ - o programa main completo
+ - o script para rodar os experimentos
+ - um Makefile exemplo do professor
+ - uma planilha exemplo para voce rodar seus experimentos
+   e incluir seus dados na pagina dadosV1
+   ao incluir os seus dados a planilha já tem os gráficos
+   como incluir?
+   * compile com comando make
+   * rode o script do professor chamado roda.sh na sua máquina
+     A MÁQUINA DEVE TER NO MÍNIMO 4 CORES E 8GB DE MEMÓRIA
+     (voce DEVE ter um mínimo de processos rodando para não atrapalhar suas medidas)
+     assim: 
+         #rode com 5milhoes de elementos em máquina com 8GB assim
+         ./roda.sh 5000000 
+         
+         
+     esse script vai produzir a saida das experiencias para
+     1 a 8 threads (10 vezes cada)
+     Voce deve copiar (contol-C) a saida do script 
+       na página dadosV1 na primeira celula dessa pagina
+       fazer (control-V nessa célula)
+       MARCANDO PARA A PLANILHA USAR COMO SEPARADORES OS CARACTERES []
+
+     Ao fazer isso as tabelas estarão ok, e as cẽlulas também
+     certifique-se que está tudo certo
+     
+     Aí basta voce ajustar as escalas dos gráficos 
+     - clicando com mouse os eixos y (esquerdo ou direito) para
+     e adequar as escalas, o prof. vai mostra na sala
+     
+
+Objetivos: 
+// Obter uma implementação paralela MAIS eficiente para 
+//   esse algoritmo "Soma de Prefixos" V1
+//   em CPUs multicore usando PThreads
+
+// será feita a soma de prefixos de 
+//  um vetor de long (ou seja, INTEIROS DE 64BITS) 
+//  usando nThreads (definida via linha de comando)
+
+// Para ESSE lab faremos:
+//   a soma de prefixos será com a operação SOMA  (+)
+
+// Funcionamento:
+//  O programa deve funcionar para nTotalElements com nThreads 
+//   Com: nTotalElements e nThreads obtidos da linha de comando
+//   (assim como a versão feita em aula para a redução)
+//  Utilização do programa:
+//  usage: ./prefixSumPth <nTotalElements> <nThreads>
+
+// ENTRADA para o algoritmo:
+// A entrada para a função PthPrefixSum será: 
+//   um vetor (GLOBAL) de nTotalElements números inteiros
+//   chamado InputVector
+//   (nTotalElements obtido da linha de comando)
+//
+// Para esse teste o vetor NÂO será lido, 
+//   - o vetor será preenchido sequencialmente pela função main
+// Assim como nossa implementação anteriror, 
+//   a inicializaçao do vetor de entrada (em main) deve ser
+//
+//      // initialize InputVector
+        for( long i = 0; i < nTotalElements; i++ ){
+	        int r = rand();  // Returns a pseudo-random integer
+	                     //    between 0 and RAND_MAX.
+		InputVector[i] = (r % 1000) - 500;
+	}
+
+// SAIDA do o algoritmo:
+// A saída da função PthPrefixSum será: 
+//   um vetor (GLOBAL) de nTotalElements números inteiros
+//   chamado OutputVector
+//   (nTotalElements obtido da linha de comando)
+//
+
+// o programa deve calcular e imprimir 
+//   o tempo e a vazão de calculo da Soma de Prefixos usando
+//   a VERSÂO 1 do algoritmo usando as idéias descritas
+//   no arquivo: 
+//     ideia-do-algoritmo-paralelo-SomaDePrefixos-Pthreads-V1.txt
+
+
+// Verificaçao de correção do programa: 
+// ------------------------------------
+// (item incluido na versao 1)
+// o programa main, antes de terminar, deve verificar
+//    se seu algoritmo paralelo gerando corretamente o vetor de saída
+//    essa verificação DEVE ser feita de forma sequencial 
+//    (ao final do main), INCLUINDO-SE O CÓDIGO ABAIXO
+//    esse código roda apenas ao final, e NÃO deve influenciar
+//    na medida de tempo feita para o algoritmo paralelo e
+//    nem deve influenciar no cálculo e resultado de VAZAO reportada
+
+void verifyPrefixSum( const TYPE *InputVec, 
+                      const TYPE *OutputVec, 
+                      long nTotalElmts )
+{
+    volatile TYPE last = InputVec[0];
+    int ok = 1;
+    for( long i=1; i<nTotalElmts ; i++ ) {
+           if( OutputVec[i] != (InputVec[i] + last) ) {
+               fprintf( stderr, "In[%ld]= %ld\n"
+                                "Out[%ld]= %ld (wrong result!)\n"
+                                "Out[%ld]= %ld (ok)\n"
+                                "last=%ld\n" , 
+                                     i, InputVec[i],
+                                     i, OutputVec[i],
+                                     i-1, OutputVec[i-1],
+                                     last );
+               ok = 0;
+               break;
+           }
+           last = OutputVec[i];    
+    }  
+    if( ok )
+       printf( "\nPrefix Sum verified correctly.\n" );
+    else
+       printf( "\nPrefix Sum DID NOT compute correctly!!!\n" );   
+}
+
+
+// O código ACIMA DEVE SER chamado ao final de main
+   da seguinte maneira para verificar que seus algoritmos funcionam:
+   
+   verifyPrefixSum( InputVector, OutputVector, nTotalElements );
+
+
+// rodar o programa 10 vezes obtendo o tempo MÍNIMO e o MÉDIO
+//  colocar TODOS os resultados em planilha
+
+// Colocar em uma planilha (tabela) os tempos para
+// 1, 2, 3, 4, 5, 6, 7, e 8 threads
+// A última coluna da tabela (planilha) deve calcular 
+//  a aceleração para 1, 2, 3, 4, 5, 6, 7, e 8 threads
+// colocando em uma planilha (tabela)
+
+// Entregar:
+//  um tar.gz contendo:
+//  -  o fonte da sua implementação em C, 
+//  -  os scripts para compilar e rodar as experiências
+//  -  a planilha preenchida com dados conforme descrito acima
+//  -  Um arquivo com seu relatório descrevendo
+//
+//       a) como você implementou (descrever seu algoritmo)
+//
+//       b) a descrição do processador que voce usou, 
+//          seu modelo e caracteristicas importantes para o experimento
+//          COLOQUE EM APENDICE NO RELATORIO A SAIDA DO COMANDO lscpu
+
+//          de preferência adicione também uma figura da 
+//          topologia dos cores do processador obtida pelo programa lstopo
+
+//       c) a descrição dos experimentos e como foram feitas as medidas
+//       
+//       d) a planilha de resultados sumarizando a vazao e aceleração
+//       e) um gráfico (obtido de sua planilha) mostrando:
+//            - no eixo X: o número de threads
+//            - no eixo Y da esquerda: a vazao para cada número de threads
+//                unir os pontos com linhas de uma certa cor C1 de sua preferência
+//            - no eixo Y da direita: a aceleração para cada número de threads
+//                unir os pontos com linhas de uma OUTRA cor C2 de sua preferência 
+
+ENTREGA:
+Em princípio o tar.gz deve ser entregue via upload na ufpr virtual
+O professor deverá incluir (em breve) a opção para entrega do lab2 na ufpr virtual
+
+--------------------------------------
+
diff --git a/ideia-do-algoritmo-paralelo-SomaDePrefixos-Pthreads-V1.txt b/ideia-do-algoritmo-paralelo-SomaDePrefixos-Pthreads-V1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..98072537f469474a6c4da8eb91214d36be1f28ab
--- /dev/null
+++ b/ideia-do-algoritmo-paralelo-SomaDePrefixos-Pthreads-V1.txt
@@ -0,0 +1,123 @@
+Trabalho 1: CI316 1sem22 UFPR
+
+Versão dessa Especificação: v1
+
+Idéia: Algoritmo de soma de prefixos com pthreads
+-------------------------------------------------
+
+Idéia geral:
+Uma idéia "inicial/basica" para algoritmo ParallelPrefixSumPth,
+cada thread pode fazer operaçoes de escrita em memória na 
+sua "faixa" de números. 
+No entanto, nesse trabalho DEVEMOS fazer uma verão mais otimizada que:
+ 
+a) opera em duas fases separadas por APENAS UMA BARREIRA
+b) na fase ANTES da barreira:
+   -  cada thread APENAS LÊ todos os 
+      elementos da sua faixa produzindo sua partialSum de elementos.
+      (O vetor global partialSum, tem uma célula por thread,
+      cada célula irá produzir sua soma parcial ANTES da barreira)
+
+c) APÓS BARREIRA:
+   - Como o vetor de somasParciais só possui uma célula por thread
+     fica fácil (e muito rápido, pois são poucas posições) cada thread
+     fazer um "for" no vetor calculando o valor do seu prefixo na
+     sua variável local myPrefixSum.
+     Assim as threads NÃO precisam esperar a thread 0 calcular isso,
+     isso tamém evita a necessidade de uma barreira adicional,
+     pois não esperamos mais a thread 0 calcular myPrefixSum.
+   - Cada thread, após calcular seu valor myPrefixSum deve, então,
+     uma um "for" apenas, calcular e escrever corretamente os valores
+     na sua faixa, produzindo a soma de prefixos na sequencia final
+     correta (ou seja em uma passada de escritas na faixa) 
+
+OBS: poderiamos usar apenas um vetor de entrada e saida (do algoritmo),
+     ou seja, seria uma implementação "in place", ou seja,
+     estaríamos alterando o vetor de entrada. 
+     
+     Essa NÂO será a especificação do trabalho 1.
+     
+     Nesse trabalho 1 devemos ter:
+     - um vetor de entrada chamado InputVector (de long ints).
+     - um vetor de saída chamado OutputVector (de long ints).
+     
+Especificamente para esse trabalho 1, devemos produzir uma funçao
+para esse algoritmo paralelo chamado ParallelPrefixSumPth.
+DEVEMOS, então, DEFINIR e usar a funçao ParallelPrefixSumPth abaixo, 
+que faz tudo, e seja ENCAPSULADA implementando com thread pool:
+  - cria as threads necessárias, e inicializa qualquel estrutura necessária
+    (e.g. barreiras, criar pool de threads, etc)
+  - O número de threads deve ser recebido como parâmetro
+  - fazer o algoritmo paralelo descrito com APENAS uma barreira
+    (se usar mais vai fica pior, e perder pontos)
+
+O prototipo dessa função deve ser:
+
+#define TYPE long         // tipo dos dados dos vetores DEVE ser long
+
+void ParallelPrefixSumPth( const TYPE *InputVec, 
+                           const TYPE *OutputVec, 
+                           long nTotalElmts,
+                           int nThreads );
+
+Obs: para ESSE trabalho 
+     vamos alocar os vetores de entrada e saída via malloc,
+     permitindo alocar grandes vetores.
+     
+--------------------------------
+
+Exemplo para vetor de 8 números e fazendo com 3 threads:
+
+Exemplo de vetor InputVector (de entrada):
+vetor InputVector: [3  1  7  .   0    4     1  .   6    3]
+
+Cada thread faz a soma de valores na sua faixa de números (chunk),
+produzindo um valor na sua posição do vetor global partialSum
+Ou seja, para esse exemplo fica:
+A thread 0 faz:
+  - calcula myPartialSum = 3+1+7  
+  - armazena no vetor global assim: PartialSum[0] = myPartialSum;
+A thread 1 faz:
+  - calcula myPartialSum = 0+4+1 
+  - armazena no vetor global assim: PartialSum[1] = myPartialSum;
+A thread 2 faz:
+  - calcula myPartialSum = 6+3
+  - armazena no vetor global assim: PartialSum[2] = myPartialSum;
+O vetor global PartialSum fica:
+PartialSum: [ 11  5  9 ]  
+  
+Após a barreira cada thread faz:
+a) calcula a soma do seu prefixo lendo o vetor global PartialSum
+   e calculando seu "prefixo" na variável local myPrefixSum
+b) produz a soma de prefixos correta na usa faixa,
+   lendo lendo a faixa do vetor de entrada e escrevendo no vetor
+   de saída, e usando o seu valor calculado em na soma myPrefixSum
+   
+vetor InputVector: [3  1  7  .   0    4     1  .   6    3]
+Assim temos:
+A thread 0 faz: 
+  a) myPrefixSum = 0   (sempre!)
+  b) produz sua faixa no vetor de saída com APENAS UM "for"
+     sua faixa fica [ 3 4 11 ... ]
+A thread 1 faz: 
+  a) myPrefixSum = 11   
+  b) produz sua faixa no vetor de saída com APENAS UM "for"
+     sua faixa fica [ ... 11 15 16 ... ]
+A thread 2 faz: 
+  a) myPrefixSum = 16   (porque? somou 11+5 do vetor PartialSum)   
+  b) produz sua faixa no vetor de saída com APENAS UM "for"
+     sua faixa fica [ ... 22 25 ]
+
+Nesse caso obtemos o seguinte vetor de saída 
+OutputVector: [3  4  11 .  11  15  16  . 22  25]
+
+
+---------------------------------
+Ou seja, vamos conferir:
+InputVector:  [3  1   7  .   0   4   1  .  6   3]
+OutputVector: [3  4  11  .  11  15  16  . 22  25]
+
+Ou seja, FUNCIONA!
+
+----------------------------------
+
diff --git a/prefixSumPth-v1 b/prefixSumPth-v1
new file mode 100755
index 0000000000000000000000000000000000000000..4b5add36068fc62ac4b18d9432a032e0ebe6e4e7
Binary files /dev/null and b/prefixSumPth-v1 differ
diff --git a/prefixSumPth-v1.c b/prefixSumPth-v1.c
new file mode 100644
index 0000000000000000000000000000000000000000..39f2fc141a11e4937e0d75561066a1ffb20003bb
--- /dev/null
+++ b/prefixSumPth-v1.c
@@ -0,0 +1,390 @@
+// TRABALHO1: CI1316 1o semestre 2023
+// Aluno:
+// GRR:
+//
+
+	///////////////////////////////////////
+	///// ATENCAO: NAO MUDAR O MAIN   /////
+        ///////////////////////////////////////
+
+#include <iostream>           // WILL USE SOME C++ features
+#include <typeinfo>
+//        template <typename T> std::string type_name();
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+
+
+#include "chrono.c"
+
+//#define DEBUG 2
+#define DEBUG 0
+
+#define MAX_THREADS 64
+
+#define MAX_TOTAL_ELEMENTS (500 * 1000 * 1000) // para maquina de 16GB de RAM 
+//#define MAX_TOTAL_ELEMENTS (200 * 1000 * 1000) // para maquina de 8GB de RAM 
+											   
+
+// ESCOLHA o tipo dos elementos usando o #define TYPE adequado abaixo
+//    a fazer a SOMA DE PREFIXOS:											   
+#define TYPE long                        // OBS: o enunciado pedia ESSE (long)
+//#define TYPE long long
+//#define TYPE double
+// OBS: para o algoritmo da soma de prefixos
+//  os tipos abaixo podem ser usados para medir tempo APENAS como referência 
+//  pois nao conseguem precisao adequada ou estouram capacidade 
+//  para quantidades razoaveis de elementos
+//#define TYPE float
+// #define TYPE int
+
+
+
+int nThreads;		// numero efetivo de threads
+					// obtido da linha de comando
+int nTotalElements; // numero total de elementos
+					// obtido da linha de comando
+
+//volatile 
+TYPE *InputVector;	// will use malloc e free to allow large (>2GB) vectors
+//volatile 
+TYPE *OutputVector;	// will use malloc e free to allow large (>2GB) vectors
+
+
+chronometer_t parallelPrefixSumTime;
+
+volatile TYPE partialSum[MAX_THREADS];
+   
+int min(int a, int b)
+{
+	if (a < b)
+		return a;
+	else
+		return b;
+}
+
+void verifyPrefixSum( const TYPE *InputVec, 
+                      const TYPE *OutputVec, 
+                      long nTotalElmts )
+{
+    volatile TYPE last = InputVec[0];
+    int ok = 1;
+    for( long i=1; i<nTotalElmts ; i++ ) {
+           if( OutputVec[i] != (InputVec[i] + last) ) {
+               fprintf( stderr, "In[%ld]= %ld\n"
+                                "Out[%ld]= %ld (wrong result!)\n"
+                                "Out[%ld]= %ld (ok)\n"
+                                "last=%ld\n" , 
+                                     i, InputVec[i],
+                                     i, OutputVec[i],
+                                     i-1, OutputVec[i-1],
+                                     last );
+               ok = 0;
+               break;
+           }
+           last = OutputVec[i];    
+    }  
+    if( ok )
+       printf( "\nPrefix Sum verified correctly.\n" );
+    else
+       printf( "\nPrefix Sum DID NOT compute correctly!!!\n" );   
+}
+
+
+typedef struct {
+	int id; 
+	long ini, fim; 
+	const TYPE *inputVec;
+	TYPE *outputVec;
+} args_t;
+		
+pthread_barrier_t partialSum_barrier;
+
+
+
+void* prefixSum(int id, const TYPE *input, TYPE * output, long start, long end){
+
+	long currentSum = 0;
+
+	for(int i = 1; i < id; i++){
+		currentSum += partialSum[i];
+	}
+
+	// printf("(%ld, %ld] -> [", start, end);
+	for(int i = start; i < end; i++){
+		output[i] = currentSum + input[i];
+		currentSum = output[i];
+		// printf("%ld ", output[i]);
+	}
+
+	// printf("]\n");
+
+
+	return NULL;
+
+}
+
+void* partialSumCalculator(void *args){
+
+	int id = ((args_t*)args)->id;
+	long ini = ((args_t*)args)->ini;
+	long end = ((args_t*)args)->fim;
+	const TYPE *InputVec = ((args_t*)args)->inputVec;
+	TYPE *OutputVec = ((args_t*)args)->outputVec;
+
+	// printf("Starting id %i\n", id);
+
+	long sum = 0;
+
+	for (int i = ini; i < end; i++) {
+		sum += InputVec[i];
+	}
+
+	partialSum[id] = sum;
+
+	pthread_barrier_wait(&partialSum_barrier);
+
+	prefixSum(id, InputVec, OutputVec, ini, end);
+
+	return NULL;
+}
+
+
+void ParallelPrefixSumPth( const TYPE *InputVec, 
+                           TYPE *OutputVec, 
+                           long nTotalElmts,
+                           int nThreads )
+{
+   pthread_t Thread[MAX_THREADS];
+   int my_thread_id[MAX_THREADS];
+   
+
+   ///////////////// INCLUIR AQUI SEU CODIGO da V1 /////////
+   
+   // criar o POOL de threads aqui!
+   
+   // voce pode criar outras funcoes para as suas threads
+   
+   //////////////////////////////////////////////////////////
+
+/*
+Criar vetor global partialSum de tamanho nThreads
+Dividir vetor InputVec em partes iguais para cada thread
+
+Cada Thread recebe um id único sequencial entre 1 e nThreads e sua sequencia do vetor inputVec
+Cada Thread lê seu vetor e salva o valor da soma de seus elementos em partialSum na posição adequada
+
+Barreira
+
+Cada Thread descobre o myPrefixSum com o vetor partialSum
+Utilizando esse valor, faz o cálculo de soma de prefixos para seus elementos
+Inserindo esses valores no local adequado no OutputVec 
+
+*/
+
+	long chunk_size = nTotalElmts/nThreads;
+	long bonus = nTotalElmts - chunk_size * nThreads;
+	
+	pthread_barrier_init(&partialSum_barrier, NULL, nThreads+1);
+
+	long start = 0;
+	long end = chunk_size;
+
+
+	my_thread_id[0] = 0;
+	for (int i = 1; i <= nThreads; i++) {
+		if (bonus){
+			end++; 
+			bonus--;
+		}
+
+		my_thread_id[i] = i;
+		
+		args_t* arguments = (args_t*) malloc(sizeof(args_t));
+		arguments->id = i;
+		arguments->ini = start;
+		arguments->fim = end;
+		arguments->inputVec = InputVec;
+		arguments->outputVec = OutputVec;
+
+		pthread_create( &Thread[i], NULL, partialSumCalculator, (void*) arguments);
+
+		start = end;
+		end = start + chunk_size;
+	}
+
+
+	pthread_barrier_wait(&partialSum_barrier);
+
+	long totalSum = 0;
+	for (int i = 1; i <= nThreads; i++) {
+		
+		// printf("Id %d: %ld\n", i, partialSum[i]);
+		totalSum += partialSum[i];
+	}
+
+	// printf("Finnish! -> Total sum = %ld\n", totalSum);
+
+
+    for (int i=1; i < nThreads; i++)
+        pthread_join(Thread[i], NULL);   // isso é necessário ?
+
+
+	return;
+}
+
+int main(int argc, char *argv[])
+{
+	long i;
+	
+	///////////////////////////////////////
+	///// ATENCAO: NAO MUDAR O MAIN   /////
+    ///////////////////////////////////////
+
+	if (argc != 3)
+	{
+		printf("usage: %s <nTotalElements> <nThreads>\n",
+			   argv[0]);
+		return 0;
+	}
+	else
+	{
+		nThreads = atoi(argv[2]);
+		if (nThreads == 0)
+		{
+			printf("usage: %s <nTotalElements> <nThreads>\n",
+				   argv[0]);
+			printf("<nThreads> can't be 0\n");
+			return 0;
+		}
+		if (nThreads > MAX_THREADS)
+		{
+			printf("usage: %s <nTotalElements> <nThreads>\n",
+				   argv[0]);
+			printf("<nThreads> must be less than %d\n", MAX_THREADS);
+			return 0;
+		}
+		nTotalElements = atoi(argv[1]);
+		if (nTotalElements > MAX_TOTAL_ELEMENTS)
+		{
+			printf("usage: %s <nTotalElements> <nThreads>\n",
+				   argv[0]);
+			printf("<nTotalElements> must be up to %d\n", MAX_TOTAL_ELEMENTS);
+			return 0;
+		}
+	}
+
+        // allocate InputVector AND OutputVector
+        InputVector = (TYPE *) malloc( nTotalElements*sizeof(TYPE) );
+        if( InputVector == NULL )
+            printf("Error allocating InputVector of %d elements (size=%ld Bytes)\n",
+                     nTotalElements, nTotalElements*sizeof(TYPE) );
+        OutputVector = (TYPE *) malloc( nTotalElements*sizeof(TYPE) );
+        if( OutputVector == NULL )
+            printf("Error allocating OutputVector of %d elements (size=%ld Bytes)\n",
+                     nTotalElements, nTotalElements*sizeof(TYPE) );
+
+
+//    #if DEBUG >= 2 
+        // Print INFOS about the reduction
+        TYPE myType;
+        long l;
+        std::cout << "Using PREFIX SUM of TYPE ";
+        
+        if( typeid(myType) == typeid(int) ) 
+		std::cout << "int" ;
+	else if( typeid(myType) == typeid(long) ) 
+		std::cout << "long" ;
+	else if( typeid(myType) == typeid(float) ) 
+		std::cout << "float" ;
+	else if( typeid(myType) == typeid(double) ) 
+		std::cout << "double" ;
+	else if( typeid(myType) == typeid(long long) ) 
+		std::cout << "long long" ;
+	else 
+	    std::cout << " ?? (UNKNOWN TYPE)" ;
+	
+	std::cout << " elements (" << sizeof(TYPE) 
+	          << " bytes each)\n" << std::endl;
+                  
+
+	/*printf("reading inputs...\n");
+	for (int i = 0; i < nTotalElements; i++)
+	{
+		scanf("%d", &InputVector[i]);
+	}*/
+	
+	// initialize InputVector
+	//srand(time(NULL));   // Initialization, should only be called once.
+        
+        int r;
+	for (long i = 0; i < nTotalElements; i++){
+	        r = rand();  // Returns a pseudo-random integer
+	                     //    between 0 and RAND_MAX.
+		InputVector[i] = (r % 1000) - 500;
+		//InputVector[i] = 1; i + 1;
+	}
+
+	printf("\n\nwill use %d threads to calculate prefix-sum of %d total elements\n", 
+	                     nThreads, nTotalElements);
+
+	chrono_reset(&parallelPrefixSumTime);
+	chrono_start(&parallelPrefixSumTime);
+
+            ////////////////////////////
+            // call it N times
+            #define NTIMES 1000
+            // #define NTIMES 1
+            TYPE globalSum;
+            TYPE *InVec = InputVector;
+            for( int i=0; i<NTIMES ; i++ ) {
+                //globalSum = parallel_reduceSum( InputVector,
+                //                                nTotalElements, nThreads );
+           
+                ParallelPrefixSumPth( InputVector, OutputVector, nTotalElements, nThreads );
+                //InputVector += (nTotalElements % MAX_TOTAL_ELEMENTS);                                
+
+                                                      
+                // wait 50 us == 50000 ns
+                // nanosleep((const struct timespec[]){{0, 50000L}}, NULL);                                
+           }     
+      
+	// Measuring time of the parallel algorithm 
+	//    including threads creation and joins...
+	chrono_stop(&parallelPrefixSumTime);
+	chrono_reportTime(&parallelPrefixSumTime, "parallelPrefixSumTime");
+
+	// calcular e imprimir a VAZAO (numero de operacoes/s)
+	double total_time_in_seconds = (double)chrono_gettotal(&parallelPrefixSumTime) /
+								   ((double)1000 * 1000 * 1000);
+	printf("total_time_in_seconds: %lf s for %d somas de prefixos\n", total_time_in_seconds, NTIMES );
+
+	double OPS = ((long)nTotalElements * NTIMES) / total_time_in_seconds;
+	printf("Throughput: %lf OP/s\n", OPS);
+
+	////////////
+        verifyPrefixSum( InputVector, OutputVector, nTotalElements );
+        //////////
+    
+    //#if NEVER
+    #if DEBUG >= 2
+        // Print InputVector
+        printf( "In: " );
+	for (int i = 0; i < nTotalElements; i++){
+		printf( "%d ", InputVector[i] );
+
+	}
+	printf( "\n" );
+
+    	// Print OutputVector
+    	printf( "Out: " );
+	for (int i = 0; i < nTotalElements; i++){
+		printf( "%d ", OutputVector[i] );
+	}
+	printf( "\n" );
+    #endif
+	return 0;
+}
diff --git a/roda-v1.sh b/roda-v1.sh
new file mode 100755
index 0000000000000000000000000000000000000000..45e488d8d0071552cee876983273e2a247e165a5
--- /dev/null
+++ b/roda-v1.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+echo "USAGE: ./run.sh <nElements>"
+echo "------------- COPIAR (ctrl-c) somente a partir da linha abaixo: -----------"
+    
+for nt in {1..8}
+do
+    echo "Executando 10 vezes com [$1] elementos e [$nt] threads:"
+    #for vez in {1..1}   # 1 vez
+    for vez in {1..10}  # 10 vezes
+    do
+        ./prefixSumPth-v1 $1 $nt | grep -oP '(?<=total_time_in_seconds: )[^ ]*'
+    done
+done
diff --git a/umaVez-v1.sh b/umaVez-v1.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b83eaab202e34bf9fdeb23572af108e1e44d1603
--- /dev/null
+++ b/umaVez-v1.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+echo "USAGE: ./run.sh <nElements>"
+echo "------------- COPIAR (ctrl-c) somente a partir da linha abaixo: -----------"
+    
+for nt in {1..8}
+do
+    echo "Executando 10 vezes com [$1] elementos e [$nt] threads:"
+    for vez in {1..1}   # 1 vez
+    #for vez in {1..10}  # 10 vezes
+    do
+        ./prefixSumPth-v1 $1 $nt | grep -oP '(?<=total_time_in_seconds: )[^ ]*'
+    done
+done