1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The Marl Authors. 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*03ce13f7SAndroid Build Coastguard Worker // 7*03ce13f7SAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*03ce13f7SAndroid Build Coastguard Worker // 9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License. 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker // This is an example application that uses Marl to find and print all the prime 16*03ce13f7SAndroid Build Coastguard Worker // numbers in the range 1 to 10000000. 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "marl/defer.h" 19*03ce13f7SAndroid Build Coastguard Worker #include "marl/scheduler.h" 20*03ce13f7SAndroid Build Coastguard Worker #include "marl/thread.h" 21*03ce13f7SAndroid Build Coastguard Worker #include "marl/ticket.h" 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker #include <vector> 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker #include <math.h> 26*03ce13f7SAndroid Build Coastguard Worker 27*03ce13f7SAndroid Build Coastguard Worker // searchMax defines the upper limit on primes to find. 28*03ce13f7SAndroid Build Coastguard Worker constexpr int searchMax = 10000000; 29*03ce13f7SAndroid Build Coastguard Worker 30*03ce13f7SAndroid Build Coastguard Worker // searchChunkSize is the number of numbers searched, per task, for primes. 31*03ce13f7SAndroid Build Coastguard Worker constexpr int searchChunkSize = 10000; 32*03ce13f7SAndroid Build Coastguard Worker 33*03ce13f7SAndroid Build Coastguard Worker // isPrime returns true if i is prime. isPrime(int i)34*03ce13f7SAndroid Build Coastguard Workerbool isPrime(int i) { 35*03ce13f7SAndroid Build Coastguard Worker auto c = static_cast<int>(sqrt(i)); 36*03ce13f7SAndroid Build Coastguard Worker for (int j = 2; j <= c; j++) { 37*03ce13f7SAndroid Build Coastguard Worker if (i % j == 0) { 38*03ce13f7SAndroid Build Coastguard Worker return false; 39*03ce13f7SAndroid Build Coastguard Worker } 40*03ce13f7SAndroid Build Coastguard Worker } 41*03ce13f7SAndroid Build Coastguard Worker return true; 42*03ce13f7SAndroid Build Coastguard Worker } 43*03ce13f7SAndroid Build Coastguard Worker main()44*03ce13f7SAndroid Build Coastguard Workerint main() { 45*03ce13f7SAndroid Build Coastguard Worker // Create a marl scheduler using the full number of logical cpus. 46*03ce13f7SAndroid Build Coastguard Worker // Bind this scheduler to the main thread so we can call marl::schedule() 47*03ce13f7SAndroid Build Coastguard Worker marl::Scheduler scheduler(marl::Scheduler::Config::allCores()); 48*03ce13f7SAndroid Build Coastguard Worker scheduler.bind(); 49*03ce13f7SAndroid Build Coastguard Worker defer(scheduler.unbind()); // unbind before destructing the scheduler. 50*03ce13f7SAndroid Build Coastguard Worker 51*03ce13f7SAndroid Build Coastguard Worker // Create a ticket queue. This will be used to ensure that the primes are 52*03ce13f7SAndroid Build Coastguard Worker // printed in ascending order. 53*03ce13f7SAndroid Build Coastguard Worker marl::Ticket::Queue queue; 54*03ce13f7SAndroid Build Coastguard Worker 55*03ce13f7SAndroid Build Coastguard Worker // Iterate over the range [1, searchMax] in steps of searchChunkSize. 56*03ce13f7SAndroid Build Coastguard Worker for (int searchBase = 1; searchBase <= searchMax; 57*03ce13f7SAndroid Build Coastguard Worker searchBase += searchChunkSize) { 58*03ce13f7SAndroid Build Coastguard Worker // Take a ticket from the ticket queue for this task. 59*03ce13f7SAndroid Build Coastguard Worker auto ticket = queue.take(); 60*03ce13f7SAndroid Build Coastguard Worker 61*03ce13f7SAndroid Build Coastguard Worker // Schedule the task. 62*03ce13f7SAndroid Build Coastguard Worker marl::schedule([=] { 63*03ce13f7SAndroid Build Coastguard Worker // Find all the primes in [searchBase, searchBase+searchChunkSize-1]. 64*03ce13f7SAndroid Build Coastguard Worker // Note this is run in parallel with the other scheduled tasks. 65*03ce13f7SAndroid Build Coastguard Worker std::vector<int> primes; 66*03ce13f7SAndroid Build Coastguard Worker for (int i = searchBase; i < searchBase + searchChunkSize; i++) { 67*03ce13f7SAndroid Build Coastguard Worker if (isPrime(i)) { 68*03ce13f7SAndroid Build Coastguard Worker primes.push_back(i); 69*03ce13f7SAndroid Build Coastguard Worker } 70*03ce13f7SAndroid Build Coastguard Worker } 71*03ce13f7SAndroid Build Coastguard Worker 72*03ce13f7SAndroid Build Coastguard Worker // Wait until the ticket is called. This ensures that the primes are 73*03ce13f7SAndroid Build Coastguard Worker // printed in ascending order. This may cause this task to yield and allow 74*03ce13f7SAndroid Build Coastguard Worker // other tasks to be executed while waiting for this ticket to be called. 75*03ce13f7SAndroid Build Coastguard Worker ticket.wait(); 76*03ce13f7SAndroid Build Coastguard Worker 77*03ce13f7SAndroid Build Coastguard Worker // Print the primes. 78*03ce13f7SAndroid Build Coastguard Worker for (auto prime : primes) { 79*03ce13f7SAndroid Build Coastguard Worker printf("%d is prime\n", prime); 80*03ce13f7SAndroid Build Coastguard Worker } 81*03ce13f7SAndroid Build Coastguard Worker 82*03ce13f7SAndroid Build Coastguard Worker // Call the next ticket so that those primes can be printed. 83*03ce13f7SAndroid Build Coastguard Worker ticket.done(); 84*03ce13f7SAndroid Build Coastguard Worker }); 85*03ce13f7SAndroid Build Coastguard Worker } 86*03ce13f7SAndroid Build Coastguard Worker 87*03ce13f7SAndroid Build Coastguard Worker // take a ticket and wait on it to ensure that all the primes have been 88*03ce13f7SAndroid Build Coastguard Worker // calculated and printed. 89*03ce13f7SAndroid Build Coastguard Worker queue.take().wait(); 90*03ce13f7SAndroid Build Coastguard Worker 91*03ce13f7SAndroid Build Coastguard Worker return 0; 92*03ce13f7SAndroid Build Coastguard Worker } 93