7 #include "xbt/xbt_os_thread.h"
\r
10 XBT_LOG_NEW_DEFAULT_CATEGORY(sem_sched,"Messages specific for this sem example");
\r
13 #define ENOBUFS 1024
\r
16 #define CTX_MAX ((unsigned int)1000)
\r
22 typedef int (*pfn_func_t)(int, char**);
\r
27 typedef struct s_job
\r
36 job_new(pfn_func_t func, int argc, char** argv);
\r
39 job_execute(job_t job);
\r
42 job_free(job_t* ref);
\r
44 /* an entry of the table of threads */
\r
45 typedef struct s_ctx
\r
51 xbt_os_thread_t imp;
\r
55 typedef struct s_shed
\r
60 }s_sched_t,* sched_t;
\r
66 unschedule(ctx_t c);
\r
69 ctx_function(void* param);
\r
75 ctx_free(ctx_t* ref);
\r
78 sched_new(int size);
\r
81 sched_add_job(sched_t sched, job_t job);
\r
84 sched_init(sched_t sched);
\r
87 sched_schedule(sched_t sched);
\r
90 sched_clean(sched_t sched);
\r
93 sched_free(sched_t* ref);
\r
96 job(int argc, char* argv[]);
\r
99 main(int argc, char* argv[])
\r
104 char arg[MAX_ARG] = {0};
\r
107 xbt_init(&argc, argv);
\r
111 INFO1("Usage: %s job count",argv[0]);
\r
112 exit(EXIT_FAILURE);
\r
116 size = atoi(argv[1]);
\r
118 /* create a new scheduler */
\r
119 sched = sched_new(size);
\r
123 INFO1("sched_new() failed : errno %d",errno);
\r
125 exit(EXIT_FAILURE);
\r
128 __argv = xbt_new0(char*,MAX_ARGS);
\r
130 for(i = 0; i < MAX_ARGS; i++)
\r
132 sprintf(arg,"arg_%d",i);
\r
133 __argv[i] = strdup(arg);
\r
134 memset(arg,0,MAX_ARG);
\r
138 for(i = 0; i < size; i++)
\r
139 sched_add_job(sched,job_new(job,(i < MAX_ARGS) ? i : MAX_ARGS,__argv));
\r
141 /* initialize the scheduler */
\r
142 if(sched_init(sched) < 0)
\r
144 sched_free(&sched);
\r
145 INFO1("sched_init() failed : errno %d\n",errno);
\r
147 exit(EXIT_FAILURE);
\r
150 /* schedule the jobs */
\r
151 if(sched_schedule(sched) < 0)
\r
153 sched_free(&sched);
\r
154 INFO1("sched_init() failed : errno %d",errno);
\r
156 exit(EXIT_FAILURE);
\r
160 if(sched_clean(sched) < 0)
\r
162 sched_free(&sched);
\r
163 INFO1("sched_init() failed : errno %d",errno);
\r
165 exit(EXIT_FAILURE);
\r
168 /* destroy the scheduler */
\r
169 sched_free(&sched);
\r
171 INFO1("sem_sched terminated with exit code %d (success)",EXIT_SUCCESS);
\r
175 return EXIT_SUCCESS;
\r
180 ctx_function(void* param)
\r
184 ctx_t ctx = (ctx_t)param;
\r
186 INFO1("Hello i'm the owner of the context %d, i'm waiting for starting",ctx->index);
\r
192 INFO1("0ups the scheduler initialization failed bye {%d}.",ctx->index);
\r
193 xbt_os_thread_exit(&exit_code);
\r
196 INFO1("I'm the owner of the context %d : I'm started",ctx->index);
\r
197 INFO0("Wait a minute, I do my job");
\r
200 exit_code = job_execute(ctx->job);
\r
202 INFO1("Have finished my job, bye {%d}\n",ctx->index);
\r
204 xbt_os_sem_release(ctx->end);
\r
206 xbt_os_thread_exit(&exit_code);
\r
209 void schedule(ctx_t c)
\r
211 xbt_os_sem_release(c->begin); /* allow C to go */
\r
212 xbt_os_sem_acquire(c->end); /* wait C's end */
\r
215 void unschedule(ctx_t c)
\r
217 xbt_os_sem_release(c->end); /* I'm done, dude */
\r
218 xbt_os_sem_acquire(c->begin); /* can I start again? */
\r
224 ctx_t ctx = xbt_new0(s_ctx_t,1);
\r
225 ctx->index = ++__next_ctx_ID;
\r
226 ctx->begin = xbt_os_sem_init(0);
\r
227 ctx->end = xbt_os_sem_init(0);
\r
235 ctx_free(ctx_t* ref)
\r
243 xbt_os_sem_destroy(ctx->begin);
\r
244 xbt_os_sem_destroy(ctx->end);
\r
245 job_free(&(ctx->job));
\r
253 sched_new(int size)
\r
263 sched = xbt_new0(s_sched_t,1);
\r
271 sched->ctxs = xbt_new0(ctx_t,size);
\r
281 sched->capacity = size;
\r
287 sched_add_job(sched_t sched, job_t job)
\r
292 if(sched->capacity < sched->size)
\r
295 sched->ctxs[(sched->size)++] = ctx_new(job);
\r
301 sched_init(sched_t sched)
\r
309 for(i = 0; i < sched->size; i++)
\r
311 sched->ctxs[i]->imp = xbt_os_thread_create("thread",ctx_function,(void*)sched->ctxs[i]);
\r
313 xbt_os_sem_acquire(sched->ctxs[i]->end);
\r
318 for(j = 0; j < i; j++)
\r
320 sched->ctxs[j]->failure = 1;
\r
321 xbt_os_sem_release(sched->ctxs[j]->begin);
\r
324 for(j = 0; j < i; j++)
\r
326 xbt_os_thread_join(sched->ctxs[j]->imp,0);
\r
328 ctx_free(&(sched->ctxs[j]));
\r
339 sched_schedule(sched_t sched)
\r
346 for(i = 0; i < sched->size; i++)
\r
347 schedule(sched->ctxs[i]);
\r
353 sched_clean(sched_t sched)
\r
360 for(i = 0; i < sched->size; i++)
\r
362 xbt_os_thread_join(sched->ctxs[i]->imp,NULL);
\r
364 ctx_free(&(sched->ctxs[i]));
\r
371 sched_free(sched_t* ref)
\r
376 free(((sched_t)(*ref))->ctxs);
\r
385 job(int argc, char** argv)
\r
389 INFO0("I'm the job : I'm going to print all the args of my commande line");
\r
391 INFO1("-- Arguments (%d):",argc);
\r
393 for(i = 0; i < argc; i++)
\r
394 INFO2(" ---- [%i] %s",i,argv[i]);
\r
400 job_new(pfn_func_t func, int argc, char** argv)
\r
405 /* todo check the parameters */
\r
406 job = xbt_new0(s_job_t,1);
\r
414 job->argv = xbt_new0(char*,argc);
\r
423 for(i = 0; i < argc; i++)
\r
424 job->argv[i] = strdup(argv[i]);
\r
433 job_execute(job_t job)
\r
438 return (*(job->func))(job->argc, job->argv);
\r
442 job_free(job_t* ref)
\r
452 for(i = 0; i < job->argc; i++)
\r
453 free(job->argv[i]);
\r