static void gen_emit_seq (rtvec vec, char *used) { for (int i = 0, len = GET_NUM_ELEM (vec); i < len; ++i) { bool last_p = (i == len - 1); rtx next = RTVEC_ELT (vec, i); if (const char *name = get_emit_function (next)) { printf (" %s (", name); gen_exp (next, DEFINE_EXPAND, used); printf (");\n"); if (!last_p && needs_barrier_p (next)) printf (" emit_barrier ();"); } else { printf (" emit ("); gen_exp (next, DEFINE_EXPAND, used); printf (", %s);\n", last_p ? "false" : "true"); } } }
/* Atiende al cliente que actualmente esta usando al servidor * * PRE: !q_is_empty(q) ("hay al menos un cliente en el servidor") * *tsal == tiempo (absoluto) de salida del servidor del cliente actual * * busy = serve_customer (q, &tsal, &wtime) * * POS: *wtime == tiempo total que estuvo en el sistema * el cliente que acaba de ser atendido * * busy => *tsal == tiempo (absoluto) de salida del servidor * del proximo cliente * * !busy => el servidor se quedo sin clientes * */ static bool serve_customer (queue_t q, double *tsal, double *wtime) { bool busy = true; assert (!q_is_empty(q)); /* Sacamos al cliente del servidor y registramos el tiempo total * que estuvo dentro del sistema */ *wtime = *tsal - q_dequeue (q); if (! q_is_empty(q) ) /* Generamos un tiempo (absoluto) de salida del servidor para * el proximo cliente que sera atendido */ *tsal = *tsal + gen_exp (Ts); else busy = false; return busy; }
/* Mete un nuevo cliente en el servidor * * PRE: ta == tiempo (absoluto) de arribo del cliente al sistema * CASE1: !busy * CASE2: busy * * accepted = receive_customer (q, ta, &busy, &tsal) * * POS: !accepted => servidor lleno, cliente rechazado * * accepted && CASE1 => el servidor estaba vacio, atendimos al cliente * *tsal contiene el proximo tiempo (abs) de salida * * accepted && CASE2 => el servidor estaba ocupado, cliente puesto en cola * *tsal no fue modificado */ static bool receive_customer (queue_t q, double ta, bool *busy, double *tsal) { bool accepted = true; if (q_is_full(q)) /* Servidor lleno => se descarta al cliente */ accepted = false; else { q_enqueue (q, ta); if (!(*busy)) { /* Servidor vacío => se atiende al cliente directamente */ *tsal = ta + gen_exp (Ts); *busy = true; } /* else: Servidor ocupado => sólo encolabamos al cliente */ } return accepted; }
static void gen_exp (rtx x, enum rtx_code subroutine_type, char *used) { RTX_CODE code; int i; int len; const char *fmt; if (x == 0) { printf ("NULL_RTX"); return; } code = GET_CODE (x); switch (code) { case MATCH_OPERAND: case MATCH_DUP: if (used) { if (used[XINT (x, 0)]) { printf ("copy_rtx (operand%d)", XINT (x, 0)); return; } used[XINT (x, 0)] = 1; } printf ("operand%d", XINT (x, 0)); return; case MATCH_OP_DUP: printf ("gen_rtx_fmt_"); for (i = 0; i < XVECLEN (x, 1); i++) printf ("e"); printf (" (GET_CODE (operand%d), ", XINT (x, 0)); if (GET_MODE (x) == VOIDmode) printf ("GET_MODE (operand%d)", XINT (x, 0)); else printf ("%smode", GET_MODE_NAME (GET_MODE (x))); for (i = 0; i < XVECLEN (x, 1); i++) { printf (",\n\t\t"); gen_exp (XVECEXP (x, 1, i), subroutine_type, used); } printf (")"); return; case MATCH_OPERATOR: printf ("gen_rtx_fmt_"); for (i = 0; i < XVECLEN (x, 2); i++) printf ("e"); printf (" (GET_CODE (operand%d)", XINT (x, 0)); printf (", %smode", GET_MODE_NAME (GET_MODE (x))); for (i = 0; i < XVECLEN (x, 2); i++) { printf (",\n\t\t"); gen_exp (XVECEXP (x, 2, i), subroutine_type, used); } printf (")"); return; case MATCH_PARALLEL: case MATCH_PAR_DUP: printf ("operand%d", XINT (x, 0)); return; case MATCH_SCRATCH: gen_rtx_scratch (x, subroutine_type); return; case PC: printf ("pc_rtx"); return; case RETURN: printf ("ret_rtx"); return; case SIMPLE_RETURN: printf ("simple_return_rtx"); return; case CLOBBER: if (REG_P (XEXP (x, 0))) { printf ("gen_hard_reg_clobber (%smode, %i)", GET_MODE_NAME (GET_MODE (XEXP (x, 0))), REGNO (XEXP (x, 0))); return; } break; case CC0: printf ("cc0_rtx"); return; case CONST_INT: if (INTVAL (x) == 0) printf ("const0_rtx"); else if (INTVAL (x) == 1) printf ("const1_rtx"); else if (INTVAL (x) == -1) printf ("constm1_rtx"); else if (-MAX_SAVED_CONST_INT <= INTVAL (x) && INTVAL (x) <= MAX_SAVED_CONST_INT) printf ("const_int_rtx[MAX_SAVED_CONST_INT + (%d)]", (int) INTVAL (x)); else if (INTVAL (x) == STORE_FLAG_VALUE) printf ("const_true_rtx"); else { printf ("GEN_INT ("); printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x)); printf (")"); } return; case CONST_DOUBLE: case CONST_FIXED: case CONST_WIDE_INT: /* These shouldn't be written in MD files. Instead, the appropriate routines in varasm.c should be called. */ gcc_unreachable (); default: break; } printf ("gen_rtx_"); print_code (code); printf (" (%smode", GET_MODE_NAME (GET_MODE (x))); fmt = GET_RTX_FORMAT (code); len = GET_RTX_LENGTH (code); for (i = 0; i < len; i++) { if (fmt[i] == '0') break; printf (",\n\t"); switch (fmt[i]) { case 'e': case 'u': gen_exp (XEXP (x, i), subroutine_type, used); break; case 'i': printf ("%u", XINT (x, i)); break; case 's': printf ("\"%s\"", XSTR (x, i)); break; case 'E': { int j; printf ("gen_rtvec (%d", XVECLEN (x, i)); for (j = 0; j < XVECLEN (x, i); j++) { printf (",\n\t\t"); gen_exp (XVECEXP (x, i, j), subroutine_type, used); } printf (")"); break; } default: gcc_unreachable (); } } printf (")"); }
int main (void) { /* Variables relacionadas con la simulacion */ queue_t q = NULL; /* Cola del servidor */ double ta = 0.0; /* Tiempo (absoluto) de arribo del proximo * * cliente al sistema */ double tsal = 0.0; /* Tiempo (absoluto) de salida del cliente * * que actualmente esta siendo atendido */ double wtime = 0.0; /* Tiempo que estuvo en el sist. un cliente */ bool busy = false, /* Servidor ocupado */ accepted = false; /* Último cliente aceptado / descartado */ double servedTime = 0.0; /* Tiempo total de atencion en un dia */ unsigned long served = 0; /* # total de clientes en un dia */ /* Variables relacionadas con los resultados de las simulaciones */ unsigned int i = 0; double sample[SIM]; /* Cocientes obtenidos de cada dia simulado */ /* NOTE: en el primer lugar de la cola 'q' estara el cliente actualmente * atendido por el servidor. * Los Q-1 lugares restantes son la cola de espera prop. dicha */ q = q_create (Q); for (i=0 ; i<SIM ; i++) { ta = 0.0; tsal = 0.0; served = 0; servedTime = 0.0; q_clean (q); /* Simulamos el arribo de los clientes mientras TIEMPO_ABSOLUTO < T */ while (ta < T) { /* Tiempo absoluto de arribo del proximo cliente */ ta += gen_exp (Ta); if (ta >= T) /* Se acabo el horario de recepción de clientes * Esto asegura que en el sub-ciclo que sigue * se atienda a todos los clientes que * actualmente están dentro del servidor */ ta = DBL_MAX; while ((ta >= tsal) && busy) { /* Ocurre antes la atencion del cliente que * actualmente esta en el servidor, * que el arribo del proximo cliente */ busy = serve_customer (q, &tsal, &wtime); servedTime += wtime; /* debug ("SALIDA # %u\ttsal %u = %.4f\n", k, k, tsal); debug ("wtime %u = %.4f\n\n", k, wtime); k++; */ } if (ta < T) { /* Metemos al cliente en el servidor, si se puede */ accepted = receive_customer (q, ta, &busy, &tsal); if (accepted) served++; } /* if (accepted) { debug ("ARRIBO # %u\tta %u = %.4f\n\n", j, j, ta); j++; } debug ("%s","Cliente rechazado (R)\n\n"); */ } /* Registramos el cociente obtenido en este dia */ debug ("sim # %u\tservedTime = %.4f\tserved = %lu\n", i, servedTime, served); if (served != 0) sample[i] = servedTime / (double) served; else sample[i] = 0.0; } debug ("%s","\nSample:"); for (i=0 ; i<SIM ; i++) debug ("\t%.8f\n", sample[i]); debug ("%s","\n"); /* Analizamos los resultados e imprimimos */ results_processing (sample, SIM); q = q_destroy (q); return 0; }