Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
bfe7b5b5ec7ce9919a6fa4d28ea3c2956182d3ae
[simgrid.git] / src / surf / workstation_ptask_L07.cpp
1 /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "workstation_ptask_L07.hpp"
8 #include "cpu.hpp"
9 #include "surf_routing.hpp"
10
11 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_workstation);
12
13 static int ptask_host_count = 0;
14 static xbt_dict_t ptask_parallel_task_link_set = NULL;
15 lmm_system_t ptask_maxmin_system = NULL;
16
17 WorkstationL07Model::WorkstationL07Model() : WorkstationModel("Workstation ptask_L07") {
18   if (!ptask_maxmin_system)
19         ptask_maxmin_system = lmm_system_new(1);
20   routing_model_create(p_networkModel->createResource("__loopback__",
21                                                           498000000, NULL,
22                                                           0.000015, NULL,
23                                                           SURF_RESOURCE_ON, NULL,
24                                                           SURF_LINK_FATPIPE, NULL));
25
26    surf_network_model = new NetworkL07Model();
27    surf_cpu_model = new CpuL07Model();
28 }
29
30 double WorkstationL07Model::shareResources(double now)
31 {
32   void *_action;
33   WorkstationL07ActionLmmPtr action;
34
35   xbt_swag_t running_actions = this->p_runningActionSet;
36   double min = this->shareResourcesMaxMin(running_actions,
37                                               ptask_maxmin_system,
38                                               bottleneck_solve);
39
40   xbt_swag_foreach(_action, running_actions) {
41         action = dynamic_cast<WorkstationL07ActionLmmPtr>(static_cast<ActionPtr>(_action));
42     if (action->m_latency > 0) {
43       if (min < 0) {
44         min = action->m_latency;
45         XBT_DEBUG("Updating min (value) with %p (start %f): %f", action,
46                action->m_start, min);
47       } else if (action->m_latency < min) {
48         min = action->m_latency;
49         XBT_DEBUG("Updating min (latency) with %p (start %f): %f", action,
50                action->m_start, min);
51       }
52     }
53   }
54
55   XBT_DEBUG("min value : %f", min);
56
57   return min;
58 }
59
60 void WorkstationL07Model::updateActionsState(double now, double delta)
61 {
62   double deltap = 0.0;
63   void *_action, *_next_action;
64   WorkstationL07ActionLmmPtr action;
65
66   xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
67     action = dynamic_cast<WorkstationL07ActionLmmPtr>(static_cast<ActionPtr>(_action));
68
69     deltap = delta;
70     if (action->m_latency > 0) {
71       if (action->m_latency > deltap) {
72         double_update(&(action->m_latency), deltap);
73         deltap = 0.0;
74       } else {
75         double_update(&(deltap), action->m_latency);
76         action->m_latency = 0.0;
77       }
78       if ((action->m_latency == 0.0) && (action->m_suspended == 0)) {
79         action->updateBound();
80         lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 1.0);
81       }
82     }
83     XBT_DEBUG("Action (%p) : remains (%g) updated by %g.",
84            action, action->m_remains, lmm_variable_getvalue(action->p_variable) * delta);
85     double_update(&(action->m_remains), lmm_variable_getvalue(action->p_variable) * delta);
86
87     if (action->m_maxDuration != NO_MAX_DURATION)
88       double_update(&(action->m_maxDuration), delta);
89
90     XBT_DEBUG("Action (%p) : remains (%g).",
91            action, action->m_remains);
92     if ((action->m_remains <= 0) &&
93         (lmm_get_variable_weight(action->p_variable) > 0)) {
94       action->m_finish = surf_get_clock();
95       action->setState(SURF_ACTION_DONE);
96     } else if ((action->m_maxDuration != NO_MAX_DURATION) &&
97                (action->m_maxDuration <= 0)) {
98       action->m_finish = surf_get_clock();
99      action->setState(SURF_ACTION_DONE);
100     } else {
101       /* Need to check that none of the model has failed */
102       lmm_constraint_t cnst = NULL;
103       int i = 0;
104       void *constraint_id = NULL;
105
106       while ((cnst = lmm_get_cnst_from_var(ptask_maxmin_system, action->p_variable,
107                                     i++))) {
108         constraint_id = lmm_constraint_id(cnst);
109
110         if (static_cast<WorkstationCLM03LmmPtr>(constraint_id)->p_stateCurrent == SURF_RESOURCE_OFF) {
111           XBT_DEBUG("Action (%p) Failed!!", action);
112           action->m_finish = surf_get_clock();
113           action->setState(SURF_ACTION_FAILED);
114           break;
115         }
116       }
117     }
118   }
119   return;
120 }
121
122 ActionPtr WorkstationL07Model::executeParallelTask(int workstation_nb,
123                                                    void **workstation_list,
124                                                  double
125                                                  *computation_amount, double
126                                                  *communication_amount,
127                                                  double rate)
128 {
129   WorkstationL07ActionLmmPtr action;
130   int i, j;
131   unsigned int cpt;
132   int nb_link = 0;
133   int nb_host = 0;
134   double latency = 0.0;
135
136   if (ptask_parallel_task_link_set == NULL)
137     ptask_parallel_task_link_set = xbt_dict_new_homogeneous(NULL);
138
139   xbt_dict_reset(ptask_parallel_task_link_set);
140
141   /* Compute the number of affected resources... */
142   for (i = 0; i < workstation_nb; i++) {
143     for (j = 0; j < workstation_nb; j++) {
144       xbt_dynar_t route=NULL;
145
146       if (communication_amount[i * workstation_nb + j] > 0) {
147         double lat=0.0;
148         unsigned int cpt;
149         void *_link;
150         LinkL07Ptr link;
151
152         routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
153                                                    static_cast<ResourcePtr>(
154                                                     surf_workstation_resource_priv(workstation_list[i])))->p_netElm,
155                                                   dynamic_cast<WorkstationL07Ptr>(
156                                                    static_cast<ResourcePtr>(
157                                                         surf_workstation_resource_priv(workstation_list[j])))->p_netElm,
158                                                   &route,
159                                                   &lat);
160         latency = MAX(latency, lat);
161
162         xbt_dynar_foreach(route, cpt, _link) {
163            link = dynamic_cast<LinkL07Ptr>(static_cast<NetworkCm02LinkPtr>(_link));
164            xbt_dict_set(ptask_parallel_task_link_set, link->m_name, link, NULL);
165         }
166       }
167     }
168   }
169
170   nb_link = xbt_dict_length(ptask_parallel_task_link_set);
171   xbt_dict_reset(ptask_parallel_task_link_set);
172
173   for (i = 0; i < workstation_nb; i++)
174     if (computation_amount[i] > 0)
175       nb_host++;
176
177   action = new WorkstationL07ActionLmm(this, 1, 0);
178   XBT_DEBUG("Creating a parallel task (%p) with %d cpus and %d links.",
179          action, workstation_nb, nb_link);
180   action->m_suspended = 0;        /* Should be useless because of the
181                                    calloc but it seems to help valgrind... */
182   action->m_workstationNb = workstation_nb;
183   action->p_workstationList = (WorkstationCLM03Ptr *) workstation_list;
184   action->p_computationAmount = computation_amount;
185   action->p_communicationAmount = communication_amount;
186   action->m_latency = latency;
187   action->m_rate = rate;
188
189   action->p_variable = lmm_variable_new(ptask_maxmin_system, action, 1.0,
190                        (action->m_rate > 0) ? action->m_rate : -1.0,
191                        workstation_nb + nb_link);
192
193   if (action->m_latency > 0)
194     lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0);
195
196   for (i = 0; i < workstation_nb; i++)
197     lmm_expand(ptask_maxmin_system,
198                static_cast<CpuLmmPtr>(dynamic_cast<WorkstationL07Ptr>(
199                                            static_cast<ResourcePtr>(
200                                             surf_workstation_resource_priv(workstation_list[i])))->p_cpu)->p_constraint,
201                action->p_variable, computation_amount[i]);
202
203   for (i = 0; i < workstation_nb; i++) {
204     for (j = 0; j < workstation_nb; j++) {
205       void *_link;
206       LinkL07Ptr link;
207       xbt_dynar_t route=NULL;
208       if (communication_amount[i * workstation_nb + j] == 0.0)
209         continue;
210
211       routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
212                                          static_cast<ResourcePtr>(
213                                           surf_workstation_resource_priv(workstation_list[i])))->p_netElm,
214                                         dynamic_cast<WorkstationL07Ptr>(
215                                          static_cast<ResourcePtr>(
216                                           surf_workstation_resource_priv(workstation_list[j])))->p_netElm,
217                                             &route, NULL);
218
219       xbt_dynar_foreach(route, cpt, _link) {
220         link = static_cast<LinkL07Ptr>(static_cast<NetworkCm02LinkPtr>(_link));
221         lmm_expand_add(ptask_maxmin_system, link->p_constraint,
222                        action->p_variable,
223                        communication_amount[i * workstation_nb + j]);
224       }
225     }
226   }
227
228   if (nb_link + nb_host == 0) {
229     action->m_cost = 1.0;
230     action->m_remains = 0.0;
231   }
232
233   return static_cast<ActionPtr>(action);
234 }
235
236 ResourcePtr WorkstationL07Model::createResource(const char *name, double power_scale,
237                                double power_initial,
238                                tmgr_trace_t power_trace,
239                                e_surf_resource_state_t state_initial,
240                                tmgr_trace_t state_trace,
241                                xbt_dict_t cpu_properties)
242 {
243   WorkstationL07Ptr wk = NULL;
244   xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
245               "Host '%s' declared several times in the platform file.",
246               name);
247
248   wk = new WorkstationL07(this, name, cpu_properties,
249                                   static_cast<RoutingEdgePtr>(xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL)),
250                                   dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(host_lib, name, SURF_CPU_LEVEL))));
251
252   xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, static_cast<ResourcePtr>(wk));
253
254   return wk;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
255 }
256
257 ActionPtr WorkstationL07Model::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst,
258                                        double size, double rate)
259 {
260   void **workstation_list = xbt_new0(void *, 2);
261   double *computation_amount = xbt_new0(double, 2);
262   double *communication_amount = xbt_new0(double, 4);
263   ActionPtr res = NULL;
264
265   workstation_list[0] = static_cast<ResourcePtr>(src);
266   workstation_list[1] = static_cast<ResourcePtr>(dst);
267   communication_amount[1] = size;
268
269   res = executeParallelTask(2, workstation_list,
270                                     computation_amount,
271                                     communication_amount, rate);
272
273   return res;
274 }
275
276 xbt_dynar_t WorkstationL07Model::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst)
277 {
278   xbt_dynar_t route=NULL;
279   routing_platf->getRouteAndLatency(src->p_netElm, dst->p_netElm, &route, NULL);
280   return route;
281 }
282
283 ResourcePtr CpuL07Model::createResource(const char *name, double power_scale,
284                                double power_initial,
285                                tmgr_trace_t power_trace,
286                                e_surf_resource_state_t state_initial,
287                                tmgr_trace_t state_trace,
288                                xbt_dict_t cpu_properties)
289 {
290   CpuL07Ptr cpu = NULL;
291   xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
292               "Host '%s' declared several times in the platform file.",
293               name);
294
295   cpu = new CpuL07(this, name, cpu_properties);
296
297   cpu->p_power.scale = power_scale;
298   xbt_assert(cpu->p_power.scale > 0, "Power has to be >0");
299
300   cpu->m_powerCurrent = power_initial;
301   if (power_trace)
302     cpu->p_power.event =
303         tmgr_history_add_trace(history, power_trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
304
305   cpu->p_stateCurrent = state_initial;
306   if (state_trace)
307     cpu->p_stateEvent =
308         tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
309
310   cpu->p_constraint =
311       lmm_constraint_new(ptask_maxmin_system, cpu,
312                          cpu->m_powerCurrent * cpu->p_power.scale);
313
314   xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
315
316   return cpu;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
317 }
318
319 ResourcePtr NetworkL07Model::createResource(const char *name,
320                                  double bw_initial,
321                                  tmgr_trace_t bw_trace,
322                                  double lat_initial,
323                                  tmgr_trace_t lat_trace,
324                                  e_surf_resource_state_t
325                                  state_initial,
326                                  tmgr_trace_t state_trace,
327                                  e_surf_link_sharing_policy_t
328                                  policy, xbt_dict_t properties)
329 {
330   LinkL07Ptr nw_link = new LinkL07(this, xbt_strdup(name), properties);
331   xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
332               "Link '%s' declared several times in the platform file.",
333               name);
334
335   nw_link->m_bwCurrent = bw_initial;
336   if (bw_trace)
337     nw_link->p_bwEvent =
338         tmgr_history_add_trace(history, bw_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
339   nw_link->p_stateCurrent = state_initial;
340   nw_link->m_latCurrent = lat_initial;
341   if (lat_trace)
342     nw_link->p_latEvent =
343         tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
344   if (state_trace)
345     nw_link->p_stateEvent =
346         tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
347
348   nw_link->p_constraint =
349       lmm_constraint_new(ptask_maxmin_system, nw_link,
350                          nw_link->m_bwCurrent);
351
352   if (policy == SURF_LINK_FATPIPE)
353     lmm_constraint_shared(nw_link->p_constraint);
354
355   xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast<NetworkCm02LinkPtr>(nw_link));
356   return nw_link;
357 }
358
359 void WorkstationL07Model::addTraces()
360 {
361   xbt_dict_cursor_t cursor = NULL;
362   char *trace_name, *elm;
363
364   if (!trace_connect_list_host_avail)
365     return;
366
367   /* Connect traces relative to cpu */
368   xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
369     tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
370     CpuL07Ptr host = (CpuL07Ptr) surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
371
372     xbt_assert(host, "Host %s undefined", elm);
373     xbt_assert(trace, "Trace %s undefined", trace_name);
374
375     host->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
376   }
377
378   xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
379     tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
380     CpuL07Ptr host = (CpuL07Ptr) surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
381
382     xbt_assert(host, "Host %s undefined", elm);
383     xbt_assert(trace, "Trace %s undefined", trace_name);
384
385     host->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
386   }
387
388   /* Connect traces relative to network */
389   xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
390     tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
391     LinkL07Ptr link = (LinkL07Ptr) xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
392
393     xbt_assert(link, "Link %s undefined", elm);
394     xbt_assert(trace, "Trace %s undefined", trace_name);
395
396     link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
397   }
398
399   xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
400     tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
401     LinkL07Ptr link = (LinkL07Ptr) xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
402
403     xbt_assert(link, "Link %s undefined", elm);
404     xbt_assert(trace, "Trace %s undefined", trace_name);
405
406     link->p_bwEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
407   }
408
409   xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
410     tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
411     LinkL07Ptr link = (LinkL07Ptr) xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
412
413     xbt_assert(link, "Link %s undefined", elm);
414     xbt_assert(trace, "Trace %s undefined", trace_name);
415
416     link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
417   }
418 }
419
420 /************
421  * Resource *
422  ************/
423
424 WorkstationL07::WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu)
425   : Resource(model, name, props), WorkstationCLM03Lmm(model, name, props, NULL, netElm, cpu)
426 {
427 }
428
429 CpuL07::CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t props)
430  : Resource(model, name, props), CpuLmm(model, name, props) {
431
432 }
433
434 LinkL07::LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props)
435  : Resource(model, name, props), NetworkCm02LinkLmm(model, name, props) {
436
437 }
438
439 bool WorkstationL07::isUsed(){
440   return lmm_constraint_used(ptask_maxmin_system, p_constraint);
441 }
442
443 void CpuL07::updateState(tmgr_trace_event_t event_type, double value, double date){
444   XBT_DEBUG("Updating cpu %s (%p) with value %g", m_name, this, value);
445   if (event_type == p_power.event) {
446         m_powerCurrent = value;
447     lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_powerCurrent * p_power.scale);
448     if (tmgr_trace_event_free(event_type))
449       p_power.event = NULL;
450   } else if (event_type == p_stateEvent) {
451     if (value > 0)
452       p_stateCurrent = SURF_RESOURCE_ON;
453     else
454       p_stateCurrent = SURF_RESOURCE_OFF;
455     if (tmgr_trace_event_free(event_type))
456       p_stateEvent = NULL;
457   } else {
458     XBT_CRITICAL("Unknown event ! \n");
459     xbt_abort();
460   }
461   return;
462 }
463
464 void LinkL07::updateState(tmgr_trace_event_t event_type, double value, double date){
465   XBT_DEBUG("Updating link %s (%p) with value=%f for date=%g", m_name, this, value, date);
466   if (event_type == p_bwEvent) {
467     m_bwCurrent = value;
468     lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_bwCurrent);
469     if (tmgr_trace_event_free(event_type))
470       p_bwEvent = NULL;
471   } else if (event_type == p_latEvent) {
472     lmm_variable_t var = NULL;
473     WorkstationL07ActionLmmPtr action;
474     lmm_element_t elem = NULL;
475
476     m_latCurrent = value;
477     while ((var = lmm_get_var_from_cnst(ptask_maxmin_system, p_constraint, &elem))) {
478       action = (WorkstationL07ActionLmmPtr) lmm_variable_id(var);
479       action->updateBound();
480     }
481     if (tmgr_trace_event_free(event_type))
482       p_latEvent = NULL;
483   } else if (event_type == p_stateEvent) {
484     if (value > 0)
485       p_stateCurrent = SURF_RESOURCE_ON;
486     else
487       p_stateCurrent = SURF_RESOURCE_OFF;
488     if (tmgr_trace_event_free(event_type))
489       p_stateEvent = NULL;
490   } else {
491     XBT_CRITICAL("Unknown event ! \n");
492     xbt_abort();
493   }
494   return;
495 }
496
497 e_surf_resource_state_t WorkstationL07::getState()
498 {
499   return p_cpu->p_stateCurrent;
500 }
501
502 e_surf_resource_state_t CpuL07::getState()
503 {
504   return p_stateCurrent;
505 }
506
507 double CpuL07::getSpeed(double load)
508 {
509   return load * p_power.scale;
510 }
511
512 double CpuL07::getAvailableSpeed()
513 {
514   return m_powerCurrent;
515 }
516
517 ActionPtr WorkstationL07::execute(double size)
518 {
519   void **workstation_list = xbt_new0(void *, 1);
520   double *computation_amount = xbt_new0(double, 1);
521   double *communication_amount = xbt_new0(double, 1);
522
523   workstation_list[0] = static_cast<ResourcePtr>(this);
524   communication_amount[0] = 0.0;
525   computation_amount[0] = size;
526
527   return static_cast<WorkstationL07ModelPtr>(p_model)->executeParallelTask(1, workstation_list,
528                                               computation_amount,
529                                      communication_amount, -1);
530 }
531
532 ActionPtr WorkstationL07::sleep(double duration)
533 {
534   WorkstationL07ActionLmmPtr action = NULL;
535
536   XBT_IN("(%s,%g)", m_name, duration);
537
538   action = dynamic_cast<WorkstationL07ActionLmmPtr>(execute(1.0));
539   action->m_maxDuration = duration;
540   action->m_suspended = 2;
541   lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0);
542
543   XBT_OUT();
544   return action;
545 }
546
547 double LinkL07::getBandwidth()
548 {
549   return m_bwCurrent;
550 }
551
552 double LinkL07::getLatency()
553 {
554   return m_latCurrent;
555 }
556
557 bool LinkL07::isShared()
558 {
559   return lmm_constraint_is_shared(p_constraint);
560 }
561
562 /**********
563  * Action *
564  **********/
565
566 WorkstationL07ActionLmm::~WorkstationL07ActionLmm(){
567   free(p_workstationList);
568   free(p_communicationAmount);
569   free(p_computationAmount);
570 #ifdef HAVE_TRACING
571   xbt_free(p_category);
572 #endif
573 }
574
575 void WorkstationL07ActionLmm::updateBound()
576 {
577   double lat_current = 0.0;
578   double lat_bound = -1.0;
579   int i, j;
580
581   for (i = 0; i < m_workstationNb; i++) {
582     for (j = 0; j < m_workstationNb; j++) {
583       xbt_dynar_t route=NULL;
584
585       if (p_communicationAmount[i * m_workstationNb + j] > 0) {
586         double lat = 0.0;
587         routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
588                                            static_cast<ResourcePtr>(
589                                             surf_workstation_resource_priv(p_workstationList[i])))->p_netElm,
590                                           dynamic_cast<WorkstationL07Ptr>(
591                                            static_cast<ResourcePtr>(
592                                                             surf_workstation_resource_priv(p_workstationList[j])))->p_netElm,
593                                                           &route, &lat);
594
595         lat_current = MAX(lat_current, lat * p_communicationAmount[i * m_workstationNb + j]);
596       }
597     }
598   }
599   lat_bound = sg_tcp_gamma / (2.0 * lat_current);
600   XBT_DEBUG("action (%p) : lat_bound = %g", this, lat_bound);
601   if ((m_latency == 0.0) && (m_suspended == 0)) {
602     if (m_rate < 0)
603       lmm_update_variable_bound(ptask_maxmin_system, p_variable, lat_bound);
604     else
605       lmm_update_variable_bound(ptask_maxmin_system, p_variable, min(m_rate, lat_bound));
606   }
607 }
608
609 int WorkstationL07ActionLmm::unref()
610 {
611   m_refcount--;
612   if (!m_refcount) {
613     xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
614     if (p_variable)
615       lmm_variable_free(ptask_maxmin_system, p_variable);
616     delete this;
617     return 1;
618   }
619   return 0;
620 }
621
622 void WorkstationL07ActionLmm::cancel()
623 {
624   setState(SURF_ACTION_FAILED);
625   return;
626 }
627
628 void WorkstationL07ActionLmm::suspend()
629 {
630   XBT_IN("(%p))", this);
631   if (m_suspended != 2) {
632     m_suspended = 1;
633     lmm_update_variable_weight(ptask_maxmin_system, p_variable, 0.0);
634   }
635   XBT_OUT();
636 }
637
638 void WorkstationL07ActionLmm::resume()
639 {
640   XBT_IN("(%p)", this);
641   if (m_suspended != 2) {
642     lmm_update_variable_weight(ptask_maxmin_system, p_variable, 1.0);
643     m_suspended = 0;
644   }
645   XBT_OUT();
646 }
647
648 bool WorkstationL07ActionLmm::isSuspended()
649 {
650   return m_suspended == 1;
651 }
652
653 void WorkstationL07ActionLmm::setMaxDuration(double duration)
654 {                               /* FIXME: should inherit */
655   XBT_IN("(%p,%g)", this, duration);
656   m_maxDuration = duration;
657   XBT_OUT();
658 }
659
660 void WorkstationL07ActionLmm::setPriority(double priority)
661 {                               /* FIXME: should inherit */
662   XBT_IN("(%p,%g)", this, priority);
663   m_priority = priority;
664   XBT_OUT();
665 }
666
667 double WorkstationL07ActionLmm::getRemains()
668 {
669   XBT_IN("(%p)", this);
670   XBT_OUT();
671   return m_remains;
672 }
673
674
675
676
677
678
679
680
681
682 static void ptask_finalize(void)
683 {
684   xbt_dict_free(&ptask_parallel_task_link_set);
685
686   delete surf_workstation_model;
687   surf_workstation_model = NULL;
688   delete surf_network_model;
689   surf_network_model = NULL;
690
691   ptask_host_count = 0;
692
693   if (ptask_maxmin_system) {
694     lmm_system_free(ptask_maxmin_system);
695     ptask_maxmin_system = NULL;
696   }
697 }
698
699 /**************************************/
700 /******* Resource Private    **********/
701 /**************************************/
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718 /**************************************/
719 /*** Resource Creation & Destruction **/
720 /**************************************/
721
722 static void ptask_parse_workstation_init(sg_platf_host_cbarg_t host)
723 {
724   static_cast<WorkstationL07ModelPtr>(surf_workstation_model)->createResource(
725       host->id,
726       host->power_peak,
727       host->power_scale,
728       host->power_trace,
729       host->initial_state,
730       host->state_trace,
731       host->properties);
732 }
733
734 static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host)
735 {
736         static_cast<CpuL07ModelPtr>(surf_cpu_model)->createResource(
737       host->id,
738       host->power_peak,
739       host->power_scale,
740       host->power_trace,
741       host->initial_state,
742       host->state_trace,
743       host->properties);
744 }
745
746
747
748 static void ptask_parse_link_init(sg_platf_link_cbarg_t link)
749 {
750   if (link->policy == SURF_LINK_FULLDUPLEX) {
751     char *link_id;
752     link_id = bprintf("%s_UP", link->id);
753     static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link_id,
754                                link->bandwidth,
755                                link->bandwidth_trace,
756                                link->latency,
757                                link->latency_trace,
758                                link->state,
759                                link->state_trace,
760                                link->policy,
761                                link->properties);
762     xbt_free(link_id);
763     link_id = bprintf("%s_DOWN", link->id);
764     static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link_id,
765                                link->bandwidth,
766                                link->bandwidth_trace,
767                                link->latency,
768                                link->latency_trace,
769                                link->state,
770                                link->state_trace,
771                                link->policy,
772                                NULL); /* FIXME: We need to deep copy the
773                                        * properties or we won't be able to free
774                                        * it */
775     xbt_free(link_id);
776   } else {
777           static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link->id,
778                                link->bandwidth,
779                                link->bandwidth_trace,
780                                link->latency,
781                                link->latency_trace,
782                                link->state,
783                                link->state_trace,
784                                link->policy,
785                                link->properties);
786   }
787
788   current_property_set = NULL;
789 }
790
791 static void ptask_add_traces(){
792   static_cast<WorkstationL07ModelPtr>(surf_workstation_model)->addTraces();
793 }
794
795 static void ptask_define_callbacks()
796 {
797   sg_platf_host_add_cb(ptask_parse_cpu_init);
798   sg_platf_host_add_cb(ptask_parse_workstation_init);
799   sg_platf_link_add_cb(ptask_parse_link_init);
800   sg_platf_postparse_add_cb(ptask_add_traces);
801 }
802
803 /**************************************/
804 /*************** Generic **************/
805 /**************************************/
806 void surf_workstation_model_init_ptask_L07(void)
807 {
808   XBT_INFO("surf_workstation_model_init_ptask_L07");
809   xbt_assert(!surf_cpu_model, "CPU model type already defined");
810   xbt_assert(!surf_network_model, "network model type already defined");
811   ptask_define_callbacks();
812   surf_workstation_model = new WorkstationL07Model();
813   ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
814   xbt_dynar_push(model_list, &model);
815 }