concurrent.c revision 540f932aeb28274e8e7ea1e8f3a8e5889b88e1d6
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher/* concurrent.c
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher *
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher * Copyright © 2013 S.Çağlar Onur <caglar@10ur.org>
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher *
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher * This program is free software; you can redistribute it and/or modify
c252d148fa8ab50aaaa8bbae7beb4d208025171dNikolai Kondrashov * it under the terms of the GNU General Public License version 2, as
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher * published by the Free Software Foundation.
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher *
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher * This program is distributed in the hope that it will be useful,
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov * but WITHOUT ANY WARRANTY; without even the implied warranty of
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov * GNU General Public License for more details.
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov *
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov * You should have received a copy of the GNU General Public License along
fd5a4eacd56700ffb08a73121aeacdc806cb0132Sumit Bose * with this program; if not, write to the Free Software Foundation, Inc.,
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher */
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include <limits.h>
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher#include <stdio.h>
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher#include <pthread.h>
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov#include <unistd.h>
428db8a58c0c149d5efccc6d788f70916c1d34d7Jakub Hrozek#define _GNU_SOURCE
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher#include <getopt.h>
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher#include <lxc/lxccontainer.h>
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic int nthreads = 5;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic int iterations = 1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic int quiet = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic int delay = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic const char *template = "busybox";
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic struct option options[] = {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher { "threads", required_argument, NULL, 'j' },
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher { "iterations", required_argument, NULL, 'i' },
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher { "template", required_argument, NULL, 't' },
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher { "delay", required_argument, NULL, 'd' },
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher { "modes", required_argument, NULL, 'm' },
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose { "quiet", no_argument, NULL, 'q' },
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose { "help", no_argument, NULL, '?' },
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose { 0, 0, 0, 0 },
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose};
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bosestatic void usage(void) {
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n"
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke "Common options :\n"
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke " -j, --threads=N Threads to run concurrently\n"
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose " (default: 5, use 1 for no threading)\n"
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose " -i, --iterations=N Number times to run the test (default: 1)\n"
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose " -t, --template=t Template to use (default: busybox)\n"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher " -d, --delay=N Delay in seconds between start and stop\n"
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher " -m, --modes=<mode,mode,...> Modes to run (create, start, stop, destroy)\n"
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher " -q, --quiet Don't produce any output\n"
8214510f125879c3b1d247f2ce981ee20b5375d1Jakub Hrozek " -?, --help Give this help list\n"
1a59af8245f183f22d87d067a90197d8e2ea958dJakub Hrozek "\n"
a5bb518446d5ce565d7ba819590a009cabb0b0b4Jakub Hrozek "Mandatory or optional arguments to long options are also mandatory or optional\n"
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "for any corresponding short options.\n\n");
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
d921c1eba437662437847279f251a0a5d8f70127Maxim
2cbdd12983eb85eddb90f64cfafb24eae5b448f4Jakub Hrozekstruct thread_args {
b9c8ce2bdd4045782c243605a1b999098bedcffcNoam Meltzer int thread_id;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher int return_code;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher char *mode;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher};
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void do_function(void *arguments)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher char name[NAME_MAX+1];
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek struct thread_args *args = arguments;
5377441d7a846461c2d9a7a870cea711360a529aNikolai Kondrashov struct lxc_container *c;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher sprintf(name, "lxc-test-concurrent-%d", args->thread_id);
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley
dbfc407eef1d9ba2469687c3ffbe7fd8bb111d94Jakub Hrozek args->return_code = 1;
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher c = lxc_container_new(name, NULL);
4b6a0d0b3d42e5fdb457f47d9adfa5e66b160256Stephen Gallagher if (!c) {
e124844907ed6973915e4d56f5442ecd07535a12Jakub Hrozek fprintf(stderr, "Unable to instantiate container (%s)\n", name);
5484044ea7bb632b915f706685fce509f6eacc48Jakub Hrozek return;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher if (strcmp(args->mode, "create") == 0) {
87d3b47abba6a40fcf809c85a2b138bc1013d9c5Jakub Hrozek if (!c->is_defined(c)) {
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek if (!c->create(c, template, NULL, NULL, 1, NULL)) {
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek fprintf(stderr, "Creating the container (%s) failed...\n", name);
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek goto out;
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else if(strcmp(args->mode, "start") == 0) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (c->is_defined(c) && !c->is_running(c)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher c->want_daemonize(c, true);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!c->start(c, false, NULL)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher fprintf(stderr, "Starting the container (%s) failed...\n", name);
054b5d4bb98973698f74d66b14ccd14394b53f10Lukas Slebodnik goto out;
054b5d4bb98973698f74d66b14ccd14394b53f10Lukas Slebodnik }
a3d176d116ceccd6a7547c128fab5df5cdd2c2b6Michal Zidek if (!c->wait(c, "RUNNING", -1)) {
a3d176d116ceccd6a7547c128fab5df5cdd2c2b6Michal Zidek fprintf(stderr, "Waiting the container (%s) to start failed...\n", name);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher goto out;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
4f6931e854c698dcb1c09f99eb330ce2fb97e7c6Lukas Slebodnik sleep(delay);
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else if(strcmp(args->mode, "stop") == 0) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (c->is_defined(c) && c->is_running(c)) {
558998ce664055a75595371118f818084d8f2b23Jan Cholasta if (!c->stop(c)) {
558998ce664055a75595371118f818084d8f2b23Jan Cholasta fprintf(stderr, "Stopping the container (%s) failed...\n", name);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta goto out;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
558998ce664055a75595371118f818084d8f2b23Jan Cholasta if (!c->wait(c, "STOPPED", -1)) {
558998ce664055a75595371118f818084d8f2b23Jan Cholasta fprintf(stderr, "Waiting the container (%s) to stop failed...\n", name);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher goto out;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else if(strcmp(args->mode, "destroy") == 0) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (c->is_defined(c) && !c->is_running(c)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!c->destroy(c)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher fprintf(stderr, "Destroying the container (%s) failed...\n", name);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher goto out;
c737e1444fb186e349e59bfa9dac4995b720b4b1Jan Zeleny }
f1828234a850dd28465425248a83a993f262918fPavel Březina }
6ea6ec5cb7d9985e2730fb9d4657624d10aed4d8Nick Guay }
b69cb1787209e85cc246eb9a944242689bfe0c46Pavel Březina args->return_code = 0;
b69cb1787209e85cc246eb9a944242689bfe0c46Pavel Březinaout:
b69cb1787209e85cc246eb9a944242689bfe0c46Pavel Březina lxc_container_put(c);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void *concurrent(void *arguments)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher do_function(arguments);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher pthread_exit(NULL);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek return NULL;
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek}
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaint main(int argc, char *argv[]) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int i, j, iter, opt;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina pthread_attr_t attr;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek pthread_t *threads;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct thread_args *args;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta char *modes_default[] = {"create", "start", "stop", "destroy", NULL};
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta char **modes = modes_default;
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozek pthread_attr_init(&attr);
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozek
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozek while ((opt = getopt_long(argc, argv, "j:i:t:d:m:q", options, NULL)) != -1) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley switch(opt) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley case 'j':
19d3aba12c70528708be9440aca66038a291f29eYassir Elley nthreads = atoi(optarg);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek break;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek case 'i':
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek iterations = atoi(optarg);
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose case 't':
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose template = optarg;
5484044ea7bb632b915f706685fce509f6eacc48Jakub Hrozek break;
5484044ea7bb632b915f706685fce509f6eacc48Jakub Hrozek case 'd':
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose delay = atoi(optarg);
3be9e26dcd169d44ae105f1b8a0674464c700b77Sumit Bose break;
45726939a48e605b0166521f94300ae04981a3a7Sumit Bose case 'q':
5484044ea7bb632b915f706685fce509f6eacc48Jakub Hrozek quiet = 1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher break;
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose case 'm': {
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose char *mode_tok, *tok, *saveptr;
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose modes = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher for (i = 0, mode_tok = optarg;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (tok = strtok_r(mode_tok, ",", &saveptr));
36ccdecd053a9ad88dce86b8c84770dc2aa11d21Simo Sorce i++, mode_tok = NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher modes = realloc(modes, sizeof(*modes) * (i+2));
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher modes[i] = tok;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher modes[i] = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher break;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher default: /* '?' */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher usage();
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher exit(EXIT_FAILURE);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
effcbdb12c7ef892f1fd92a745cb33a08ca4ba30Stephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher threads = malloc(sizeof(*threads) * nthreads);
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek args = malloc(sizeof(*args) * nthreads);
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher if (threads == NULL || args == NULL) {
fe60346714a73ac3987f786731389320633dd245Pavel Březina fprintf(stderr, "Unable malloc enough memory for %d threads\n", nthreads);
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose exit(EXIT_FAILURE);
2d257ccf620ce1b611f89cec8f0a94c88c2f2881Sumit Bose }
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek for (iter = 1; iter <= iterations; iter++) {
e5e8252ec48bfdd4e7529debc705c8e090264b9aSumit Bose int fd;
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březina fd = open("/", O_RDONLY);
8359bf07a2e6c0181251ce8d5d9160dc57546c55Stephen Gallagher if (!quiet)
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březina printf("\nIteration %d/%d maxfd:%d\n", iter, iterations, fd);
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březina close(fd);
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina
80314a6f3ea8d81abe73d501d5b953a256cb2167Pavel Březina for (i = 0; modes[i];i++) {
80314a6f3ea8d81abe73d501d5b953a256cb2167Pavel Březina if (!quiet)
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina printf("Executing (%s) for %d containers...\n", modes[i], nthreads);
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina for (j = 0; j < nthreads; j++) {
80314a6f3ea8d81abe73d501d5b953a256cb2167Pavel Březina args[j].thread_id = j;
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek args[j].mode = modes[i];
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek if (nthreads > 1) {
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) {
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek perror("pthread_create() error");
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek exit(EXIT_FAILURE);
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else {
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek do_function(&args[j]);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek }
a65a64aee968bd2ac18156ced15a1e2509a8acbaAbhishek Singh }
ae6c1596225c65bec2a2dabff9eee4e3e0691181Abhishek Singh
2a9af1f71887f02935e2fb6ad5023afba5b6d43eSumit Bose for (j = 0; j < nthreads; j++) {
d00ffd2cb4e2f17c75b466178bb645b5c9317909Pallavi Jha if (nthreads > 1) {
461da2984c747708e8badd27fa55ef879f40e712Pallavi Jha if (pthread_join(threads[j], NULL) != 0) {
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek perror("pthread_join() error");
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek exit(EXIT_FAILURE);
d064fef06dcbcb5f6c1be03e286b1a3433d6dfd7Sumit Bose }
e046ae03d0f55b1c8b0ec2fa6139bf86a3449adfPavel Březina }
939246537b0b9a4af6862c513d3919501ad57d92Sumit Bose if (args[j].return_code) {
f69f3581658351003a6d9245045e41d0efb85022Sumit Bose fprintf(stderr, "thread returned error %d", args[j].return_code);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek exit(EXIT_FAILURE);
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek }
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek }
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
f43c6a9ae2aea13b7a83fd932139f9352efbfcadPavel Březina
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek free(args);
50b8a36b0932a510e825ed1ad8103f81ead2b7d8Pavel Reichl free(threads);
50b8a36b0932a510e825ed1ad8103f81ead2b7d8Pavel Reichl pthread_attr_destroy(&attr);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek exit(EXIT_SUCCESS);
a524965fbe0551f1b3a68f1e5c7a5689a652998fSumit Bose}
526a15438525417cd701f837d7085b7f8c8a6325Jakub Hrozek