Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix copyright headers
[simgrid.git] / examples / xbt / sem_sched.c
index 6549403..b0f2f1d 100644 (file)
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <errno.h>\r
-\r
-\r
-#include "xbt/xbt_os_thread.h"\r
-#include "xbt.h"\r
-#include "xbt/log.h"\r
-XBT_LOG_NEW_DEFAULT_CATEGORY(sem_sched,"Messages specific for this sem example");\r
-\r
-#ifndef ENOBUFS\r
-#define ENOBUFS                1024\r
-#endif\r
-\r
-#define CTX_MAX                        ((unsigned int)1000)\r
-\r
-\r
-#define MAX_ARG                                                30\r
-#define MAX_ARGS                                       10\r
-\r
-typedef int (*pfn_func_t)(int, char**);\r
-\r
-static int\r
-__next_ctx_ID = 0;\r
-\r
-typedef struct s_job\r
-{\r
-       pfn_func_t func;\r
-       int argc;\r
-       char** argv;\r
-}s_job_t,* job_t;\r
-\r
-\r
-job_t\r
-job_new(pfn_func_t func, int argc, char** argv);\r
-\r
-int\r
-job_execute(job_t job);\r
-\r
-int\r
-job_free(job_t* ref);\r
-\r
-/* an entry of the table of threads */\r
-typedef struct s_ctx\r
-{\r
-       xbt_os_sem_t begin;\r
-       xbt_os_sem_t end;\r
-       int failure;\r
-       job_t job;\r
-       xbt_os_thread_t imp;\r
-       int index;\r
-}s_ctx_t,* ctx_t;\r
-\r
-typedef struct s_shed\r
-{\r
-       ctx_t* ctxs;\r
-       int size;\r
-       int capacity;\r
-}s_sched_t,* sched_t;\r
-\r
-\r
-void \r
-schedule(ctx_t c);\r
-void \r
-unschedule(ctx_t c);\r
-\r
-void*\r
-ctx_function(void* param);\r
-\r
-ctx_t \r
-ctx_new(job_t job);\r
-\r
-int \r
-ctx_free(ctx_t* ref);\r
-\r
-sched_t\r
-sched_new(int size);\r
-\r
-int\r
-sched_add_job(sched_t sched, job_t job);\r
-\r
-int\r
-sched_init(sched_t sched);\r
-\r
-int\r
-sched_schedule(sched_t sched);\r
-\r
-int\r
-sched_clean(sched_t sched);\r
-\r
-int\r
-sched_free(sched_t* ref);\r
-\r
-int\r
-job(int argc, char* argv[]);\r
-\r
-int\r
-main(int argc, char* argv[])\r
-{\r
-       sched_t sched;\r
-       int i, size;\r
-       char** __argv;\r
-       char arg[MAX_ARG] = {0};\r
-       \r
-       \r
-       xbt_init(&argc, argv);\r
-       \r
-       if(argc != 2) \r
-       {\r
-               INFO1("Usage: %s job count",argv[0]);\r
-               exit(EXIT_FAILURE);\r
-       }  \r
-       \r
-       \r
-       size = atoi(argv[1]);\r
-       \r
-       /* create a new scheduler */\r
-       sched = sched_new(size);\r
-       \r
-       if(!sched)\r
-       {\r
-               INFO1("sched_new() failed : errno %d",errno);\r
-               xbt_exit();\r
-               exit(EXIT_FAILURE);\r
-       }\r
-       \r
-       __argv = xbt_new0(char*,MAX_ARGS);\r
-       \r
-       for(i = 0; i < MAX_ARGS; i++)\r
-       {\r
-               sprintf(arg,"arg_%d",i);\r
-               __argv[i] = strdup(arg);\r
-               memset(arg,0,MAX_ARG);\r
-               \r
-       }\r
-       \r
-       for(i = 0; i < size; i++)\r
-               sched_add_job(sched,job_new(job,(i < MAX_ARGS) ? i : MAX_ARGS,__argv));\r
-       \r
-       /* initialize the scheduler */\r
-       if(sched_init(sched) < 0)\r
-       {\r
-               sched_free(&sched);\r
-               INFO1("sched_init() failed : errno %d\n",errno);\r
-               xbt_exit();\r
-               exit(EXIT_FAILURE);\r
-       }\r
-       \r
-       /* schedule the jobs */\r
-       if(sched_schedule(sched) < 0)\r
-       {\r
-               sched_free(&sched);\r
-               INFO1("sched_init() failed : errno %d",errno);\r
-               xbt_exit();\r
-               exit(EXIT_FAILURE);\r
-       }\r
-       \r
-       /* cleanup */\r
-       if(sched_clean(sched) < 0)\r
-       {\r
-               sched_free(&sched);\r
-               INFO1("sched_init() failed : errno %d",errno);\r
-               xbt_exit();\r
-               exit(EXIT_FAILURE);\r
-       }\r
-       \r
-       /* destroy the scheduler */\r
-       sched_free(&sched);\r
-       \r
-       INFO1("sem_sched terminated with exit code %d (success)",EXIT_SUCCESS);\r
-\r
-       xbt_exit();\r
-       \r
-       return EXIT_SUCCESS;\r
-               \r
-}\r
-\r
-void*\r
-ctx_function(void* param)\r
-{\r
-       int i = 0;\r
-       int exit_code = 1;\r
-       ctx_t ctx = (ctx_t)param;\r
-       \r
-       INFO1("Hello i'm the owner of the context %d, i'm waiting for starting",ctx->index);\r
-       \r
-       unschedule(ctx);\r
-       \r
-       if(ctx->failure)\r
-       {\r
-               INFO1("0ups the scheduler initialization failed bye {%d}.",ctx->index);\r
-               xbt_os_thread_exit(&exit_code);\r
-       }\r
-       \r
-       INFO1("I'm the owner of the context %d : I'm started",ctx->index);\r
-       INFO0("Wait a minute, I do my job");\r
-       \r
-       /* do its job */\r
-       exit_code = job_execute(ctx->job);\r
-       \r
-       INFO1("Have finished my job, bye {%d}\n",ctx->index);\r
-       \r
-       xbt_os_sem_release(ctx->end);\r
-       \r
-       xbt_os_thread_exit(&exit_code);\r
-}\r
-\r
-void schedule(ctx_t c) \r
-{\r
-       xbt_os_sem_release(c->begin);   /* allow C to go                */\r
-       xbt_os_sem_acquire(c->end);     /* wait C's end                 */\r
-}\r
-\r
-void unschedule(ctx_t c) \r
-{\r
-   xbt_os_sem_release(c->end);         /* I'm done, dude               */\r
-   xbt_os_sem_acquire(c->begin);       /* can I start again?   */\r
-}\r
-\r
-ctx_t \r
-ctx_new(job_t job)\r
-{\r
-       ctx_t ctx = xbt_new0(s_ctx_t,1);\r
-       ctx->index = ++__next_ctx_ID;\r
-       ctx->begin = xbt_os_sem_init(0);\r
-       ctx->end = xbt_os_sem_init(0);\r
-       ctx->failure = 0;\r
-       ctx->job = job;\r
-       \r
-       return ctx;\r
-}\r
-\r
-int \r
-ctx_free(ctx_t* ref)\r
-{\r
-       ctx_t ctx;\r
-       if(!(*ref))\r
-               return EINVAL;\r
-       \r
-       ctx = *ref;\r
-       \r
-       xbt_os_sem_destroy(ctx->begin);\r
-       xbt_os_sem_destroy(ctx->end);\r
-       job_free(&(ctx->job));\r
-       free(ctx);\r
-       *ref = NULL;\r
-       \r
-       return 0;\r
-}\r
-\r
-sched_t\r
-sched_new(int size)\r
-{\r
-       sched_t sched;\r
-       \r
-       if(size <= 0)\r
-       {\r
-               errno = EINVAL;\r
-               return NULL;\r
-       }\r
-       \r
-       sched = xbt_new0(s_sched_t,1);\r
-       \r
-       if(!sched)\r
-       {\r
-               errno = ENOMEM;\r
-               return NULL;\r
-       }\r
-               \r
-       sched->ctxs = xbt_new0(ctx_t,size);\r
-       \r
-       if(!(sched->ctxs))\r
-       {\r
-               errno = ENOMEM;\r
-               free(sched);\r
-               return NULL;\r
-       }\r
-       \r
-       sched->size = 0;\r
-       sched->capacity = size;\r
-       \r
-       return sched;\r
-}\r
-\r
-int\r
-sched_add_job(sched_t sched, job_t job)\r
-{\r
-       if(!sched || !job)\r
-               return EINVAL;\r
-       \r
-       if(sched->capacity < sched->size)\r
-               return ENOBUFS;\r
-               \r
-       sched->ctxs[(sched->size)++] = ctx_new(job);\r
-       \r
-       return 0;\r
-}\r
-\r
-int\r
-sched_init(sched_t sched)\r
-{\r
-       int i,j;\r
-       int success = 1;\r
-       \r
-       if(!sched)\r
-               return EINVAL;\r
-       \r
-       for(i = 0; i < sched->size; i++)\r
-       {       \r
-               sched->ctxs[i]->imp = xbt_os_thread_create("thread",ctx_function,(void*)sched->ctxs[i]);\r
-               \r
-               xbt_os_sem_acquire(sched->ctxs[i]->end);\r
-       }\r
-       \r
-       if(!success)\r
-       {\r
-               for(j = 0; j < i; j++)\r
-               {\r
-                       sched->ctxs[j]->failure = 1;\r
-                       xbt_os_sem_release(sched->ctxs[j]->begin);\r
-               }\r
-                       \r
-               for(j = 0; j < i; j++)\r
-               {\r
-                       xbt_os_thread_join(sched->ctxs[j]->imp,0);\r
-                       \r
-                       ctx_free(&(sched->ctxs[j]));\r
-               }\r
-               \r
-               return -1;\r
-                                       \r
-       }\r
-       \r
-       return 0;\r
-}\r
-\r
-int\r
-sched_schedule(sched_t sched)\r
-{\r
-       int i;\r
-       \r
-       if(!sched)\r
-               return EINVAL;\r
-               \r
-       for(i = 0; i < sched->size; i++)\r
-               schedule(sched->ctxs[i]);\r
-               \r
-       return 0;\r
-}\r
-\r
-int\r
-sched_clean(sched_t sched)\r
-{\r
-       int i;\r
-       \r
-       if(!sched)\r
-               return EINVAL;\r
-               \r
-       for(i = 0; i < sched->size; i++)\r
-       {\r
-               xbt_os_thread_join(sched->ctxs[i]->imp,NULL);\r
-               \r
-               ctx_free(&(sched->ctxs[i]));\r
-       }\r
-       \r
-       return 0;\r
-}\r
-\r
-int\r
-sched_free(sched_t* ref)\r
-{\r
-       if(*ref)\r
-               return EINVAL;\r
-               \r
-       free(((sched_t)(*ref))->ctxs);\r
-       \r
-       *ref = NULL;\r
-       \r
-       return 0;\r
-}\r
-\r
-\r
-int\r
-job(int argc, char** argv)\r
-{\r
-       int i = 0;\r
-       \r
-       INFO0("I'm the job : I'm going to print all the args of my commande line");\r
-       \r
-       INFO1("-- Arguments (%d):",argc);\r
-       \r
-       for(i = 0; i < argc; i++)\r
-               INFO2("  ---- [%i] %s",i,argv[i]);\r
-               \r
-       return 0;\r
-}\r
-\r
-job_t\r
-job_new(pfn_func_t func, int argc, char** argv)\r
-{\r
-       job_t job;\r
-       int i;\r
-       \r
-       /* todo check the parameters */\r
-       job = xbt_new0(s_job_t,1);\r
-       \r
-       if(!job)\r
-       {\r
-               errno = ENOMEM;\r
-               return NULL;\r
-       }\r
-       \r
-       job->argv = xbt_new0(char*,argc);\r
-       \r
-       if(!(job->argv))\r
-       {\r
-               free(job);\r
-               errno = ENOMEM;\r
-               return NULL;\r
-       }\r
-       \r
-       for(i = 0; i < argc; i++)\r
-               job->argv[i] = strdup(argv[i]);\r
-       \r
-       job->func = func;       \r
-       job->argc = argc;\r
-       \r
-       return job;\r
-}\r
-\r
-int\r
-job_execute(job_t job)\r
-{\r
-       if(!job)\r
-               return EINVAL;\r
-               \r
-       return (*(job->func))(job->argc, job->argv);\r
-}\r
-\r
-int\r
-job_free(job_t* ref)\r
-{\r
-       job_t job;\r
-       int i;\r
-       \r
-       if(!(*ref))\r
-               return EINVAL;\r
-               \r
-       job = *ref;\r
-       \r
-       for(i = 0; i < job->argc; i++)\r
-               free(job->argv[i]);\r
-       \r
-       free(job->argv);\r
-       free(*ref);\r
-       *ref = NULL;\r
-       \r
-       return 0;\r
-}\r
-\r
-\r
-\r
+/* Copyright (c) 2007, 2008. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+
+#include "xbt/xbt_os_thread.h"
+#include "xbt.h"
+#include "xbt/log.h"
+XBT_LOG_NEW_DEFAULT_CATEGORY(sem_sched,"Messages specific for this sem example");
+
+#ifndef ENOBUFS
+#define ENOBUFS                1024
+#endif
+
+#define CTX_MAX                        ((unsigned int)1000)
+
+
+#define MAX_ARG                                                30
+#define MAX_ARGS                                       10
+
+typedef int (*pfn_func_t)(int, char**);
+
+static int
+__next_ctx_ID = 0;
+
+typedef struct s_job
+{
+       pfn_func_t func;
+       int argc;
+       char** argv;
+}s_job_t,* job_t;
+
+
+job_t
+job_new(pfn_func_t func, int argc, char** argv);
+
+int
+job_execute(job_t job);
+
+int
+job_free(job_t* ref);
+
+/* an entry of the table of threads */
+typedef struct s_ctx
+{
+       xbt_os_sem_t begin;
+       xbt_os_sem_t end;
+       int failure;
+       job_t job;
+       xbt_os_thread_t imp;
+       int index;
+}s_ctx_t,* ctx_t;
+
+typedef struct s_shed
+{
+       ctx_t* ctxs;
+       int size;
+       int capacity;
+}s_sched_t,* sched_t;
+
+
+void 
+schedule(ctx_t c);
+void 
+unschedule(ctx_t c);
+
+void*
+ctx_function(void* param);
+
+ctx_t 
+ctx_new(job_t job);
+
+int 
+ctx_free(ctx_t* ref);
+
+sched_t
+sched_new(int size);
+
+int
+sched_add_job(sched_t sched, job_t job);
+
+int
+sched_init(sched_t sched);
+
+int
+sched_schedule(sched_t sched);
+
+int
+sched_clean(sched_t sched);
+
+int
+sched_free(sched_t* ref);
+
+int
+job(int argc, char* argv[]);
+
+int
+main(int argc, char* argv[])
+{
+       sched_t sched;
+       int i, size;
+       char** __argv;
+       char arg[MAX_ARG] = {0};
+       
+       
+       xbt_init(&argc, argv);
+       
+       if(argc != 2) 
+       {
+               INFO1("Usage: %s job count",argv[0]);
+               exit(EXIT_FAILURE);
+       }  
+       
+       
+       size = atoi(argv[1]);
+       
+       /* create a new scheduler */
+       sched = sched_new(size);
+       
+       if(!sched)
+       {
+               INFO1("sched_new() failed : errno %d",errno);
+               xbt_exit();
+               exit(EXIT_FAILURE);
+       }
+       
+       __argv = xbt_new0(char*,MAX_ARGS);
+       
+       for(i = 0; i < MAX_ARGS; i++)
+       {
+               sprintf(arg,"arg_%d",i);
+               __argv[i] = strdup(arg);
+               memset(arg,0,MAX_ARG);
+               
+       }
+       
+       for(i = 0; i < size; i++)
+               sched_add_job(sched,job_new(job,(i < MAX_ARGS) ? i : MAX_ARGS,__argv));
+       
+       /* initialize the scheduler */
+       if(sched_init(sched) < 0)
+       {
+               sched_free(&sched);
+               INFO1("sched_init() failed : errno %d\n",errno);
+               xbt_exit();
+               exit(EXIT_FAILURE);
+       }
+       
+       /* schedule the jobs */
+       if(sched_schedule(sched) < 0)
+       {
+               sched_free(&sched);
+               INFO1("sched_init() failed : errno %d",errno);
+               xbt_exit();
+               exit(EXIT_FAILURE);
+       }
+       
+       /* cleanup */
+       if(sched_clean(sched) < 0)
+       {
+               sched_free(&sched);
+               INFO1("sched_init() failed : errno %d",errno);
+               xbt_exit();
+               exit(EXIT_FAILURE);
+       }
+       
+       /* destroy the scheduler */
+       sched_free(&sched);
+       
+       INFO1("sem_sched terminated with exit code %d (success)",EXIT_SUCCESS);
+
+       xbt_exit();
+       
+       return EXIT_SUCCESS;
+               
+}
+
+void*
+ctx_function(void* param)
+{
+       int i = 0;
+       int exit_code = 1;
+       ctx_t ctx = (ctx_t)param;
+       
+       INFO1("Hello i'm the owner of the context %d, i'm waiting for starting",ctx->index);
+       
+       unschedule(ctx);
+       
+       if(ctx->failure)
+       {
+               INFO1("0ups the scheduler initialization failed bye {%d}.",ctx->index);
+               xbt_os_thread_exit(&exit_code);
+       }
+       
+       INFO1("I'm the owner of the context %d : I'm started",ctx->index);
+       INFO0("Wait a minute, I do my job");
+       
+       /* do its job */
+       exit_code = job_execute(ctx->job);
+       
+       INFO1("Have finished my job, bye {%d}\n",ctx->index);
+       
+       xbt_os_sem_release(ctx->end);
+       
+       xbt_os_thread_exit(&exit_code);
+}
+
+void schedule(ctx_t c) 
+{
+       xbt_os_sem_release(c->begin);   /* allow C to go                */
+       xbt_os_sem_acquire(c->end);     /* wait C's end                 */
+}
+
+void unschedule(ctx_t c) 
+{
+   xbt_os_sem_release(c->end);         /* I'm done, dude               */
+   xbt_os_sem_acquire(c->begin);       /* can I start again?   */
+}
+
+ctx_t 
+ctx_new(job_t job)
+{
+       ctx_t ctx = xbt_new0(s_ctx_t,1);
+       ctx->index = ++__next_ctx_ID;
+       ctx->begin = xbt_os_sem_init(0);
+       ctx->end = xbt_os_sem_init(0);
+       ctx->failure = 0;
+       ctx->job = job;
+       
+       return ctx;
+}
+
+int 
+ctx_free(ctx_t* ref)
+{
+       ctx_t ctx;
+       if(!(*ref))
+               return EINVAL;
+       
+       ctx = *ref;
+       
+       xbt_os_sem_destroy(ctx->begin);
+       xbt_os_sem_destroy(ctx->end);
+       job_free(&(ctx->job));
+       free(ctx);
+       *ref = NULL;
+       
+       return 0;
+}
+
+sched_t
+sched_new(int size)
+{
+       sched_t sched;
+       
+       if(size <= 0)
+       {
+               errno = EINVAL;
+               return NULL;
+       }
+       
+       sched = xbt_new0(s_sched_t,1);
+       
+       if(!sched)
+       {
+               errno = ENOMEM;
+               return NULL;
+       }
+               
+       sched->ctxs = xbt_new0(ctx_t,size);
+       
+       if(!(sched->ctxs))
+       {
+               errno = ENOMEM;
+               free(sched);
+               return NULL;
+       }
+       
+       sched->size = 0;
+       sched->capacity = size;
+       
+       return sched;
+}
+
+int
+sched_add_job(sched_t sched, job_t job)
+{
+       if(!sched || !job)
+               return EINVAL;
+       
+       if(sched->capacity < sched->size)
+               return ENOBUFS;
+               
+       sched->ctxs[(sched->size)++] = ctx_new(job);
+       
+       return 0;
+}
+
+int
+sched_init(sched_t sched)
+{
+       int i,j;
+       int success = 1;
+       
+       if(!sched)
+               return EINVAL;
+       
+       for(i = 0; i < sched->size; i++)
+       {       
+               sched->ctxs[i]->imp = xbt_os_thread_create("thread",ctx_function,(void*)sched->ctxs[i]);
+               
+               xbt_os_sem_acquire(sched->ctxs[i]->end);
+       }
+       
+       if(!success)
+       {
+               for(j = 0; j < i; j++)
+               {
+                       sched->ctxs[j]->failure = 1;
+                       xbt_os_sem_release(sched->ctxs[j]->begin);
+               }
+                       
+               for(j = 0; j < i; j++)
+               {
+                       xbt_os_thread_join(sched->ctxs[j]->imp,0);
+                       
+                       ctx_free(&(sched->ctxs[j]));
+               }
+               
+               return -1;
+                                       
+       }
+       
+       return 0;
+}
+
+int
+sched_schedule(sched_t sched)
+{
+       int i;
+       
+       if(!sched)
+               return EINVAL;
+               
+       for(i = 0; i < sched->size; i++)
+               schedule(sched->ctxs[i]);
+               
+       return 0;
+}
+
+int
+sched_clean(sched_t sched)
+{
+       int i;
+       
+       if(!sched)
+               return EINVAL;
+               
+       for(i = 0; i < sched->size; i++)
+       {
+               xbt_os_thread_join(sched->ctxs[i]->imp,NULL);
+               
+               ctx_free(&(sched->ctxs[i]));
+       }
+       
+       return 0;
+}
+
+int
+sched_free(sched_t* ref)
+{
+       if(*ref)
+               return EINVAL;
+               
+       free(((sched_t)(*ref))->ctxs);
+       
+       *ref = NULL;
+       
+       return 0;
+}
+
+
+int
+job(int argc, char** argv)
+{
+       int i = 0;
+       
+       INFO0("I'm the job : I'm going to print all the args of my commande line");
+       
+       INFO1("-- Arguments (%d):",argc);
+       
+       for(i = 0; i < argc; i++)
+               INFO2("  ---- [%i] %s",i,argv[i]);
+               
+       return 0;
+}
+
+job_t
+job_new(pfn_func_t func, int argc, char** argv)
+{
+       job_t job;
+       int i;
+       
+       /* todo check the parameters */
+       job = xbt_new0(s_job_t,1);
+       
+       if(!job)
+       {
+               errno = ENOMEM;
+               return NULL;
+       }
+       
+       job->argv = xbt_new0(char*,argc);
+       
+       if(!(job->argv))
+       {
+               free(job);
+               errno = ENOMEM;
+               return NULL;
+       }
+       
+       for(i = 0; i < argc; i++)
+               job->argv[i] = strdup(argv[i]);
+       
+       job->func = func;       
+       job->argc = argc;
+       
+       return job;
+}
+
+int
+job_execute(job_t job)
+{
+       if(!job)
+               return EINVAL;
+               
+       return (*(job->func))(job->argc, job->argv);
+}
+
+int
+job_free(job_t* ref)
+{
+       job_t job;
+       int i;
+       
+       if(!(*ref))
+               return EINVAL;
+               
+       job = *ref;
+       
+       for(i = 0; i < job->argc; i++)
+               free(job->argv[i]);
+       
+       free(job->argv);
+       free(*ref);
+       *ref = NULL;
+       
+       return 0;
+}
+
+
+