Memoria Compartida Distribuida Jos A Gil Salinas Universidad
Memoria Compartida Distribuida José A. Gil Salinas Universidad Politécnica de Valencia Departamento de Informática de Sistemas y Computadores © José A. Gil
Introducción Ä Memoria compartida distribuida: m Esfuerzo para combinar las mejores características de dos aproximaciones diferentes l SMP - shared memory multiprocessing l DCS - distributed computing systems Ä SMP Modelo de programación simple, basado en un espacio de direcciones compartido No es escalable Ä DCS Es escalable Modelo de programación difícil de usar, basado en varios espacios de dirección distintos, y paso de mensajes © José A. Gil 1
Modelo de programación: Locks y Barreras Ä Lock (bloqueo): mecanismo de protección en el acceso a recursos (memoria) compartidos. m Operaciones: aquire y release Ä Barrera: mecanismo de sincronización adicional a los locks. m Sean N procesos distribuidos cooperantes. l Cada vez que uno de ellos encuentra una barrera, se bloquea hasta que el resto (N-1) alcanza la misma barrera. l Se utilizan para separar fases del cómputo. l Es un punto donde se alcanza total consistencia, incluyendo datos externos a secciones críticas. l Se asemejan a un par release-acquire. m Epoch: porción de código comprendido entre dos barreras. © José A. Gil 2
Barreras © José A. Gil 3
Estructura y organización de un sistema DSM © José A. Gil 4
Introducción Ä Características principales de DSM m Modelo de programación simple de usar m Y es escalable Ä Modelo de programación simple m Es una consecuencia del hecho que DSM está basado en un solo espacio de dirección lógico. Ä Escalabilidad m Es una consecuencia del hecho que porciones diferentes del espacio de direcciones (qué es lógicamente único) están implementadas en nodos de proceso diferentes (físicamente distintos). © José A. Gil 5
DSM y disciplinas asociadas © José A. Gil 6
DSM y su implementación Ä Software m Primeras implementaciones (multicomputadores y clusters con paso de mensajes) m Nivel: l Biblioteca de rutinas l Primitivas insertadas por el compilador l Sistema operativo n En el núcleo n Fuera del núcleo m Fáciles de construir y baratas de implementar m Lentas e ineficientes © José A. Gil 7
DSM y su implementación Ä Hardware m Rápidas y eficientes m Relativamente complejas y caras Ä Mixta (híbrida) m Cada mecanismo puede ser implementado en el nivel adecuado (Hw o Sw) m La mejor aproximación coste/prestaciones © José A. Gil 8
Organización interna de los datos compartidos Ä Los datos compartidos pueden ser de cualquier tipo m No estructurados m Estructurados l Tipos de datos tradicionales l Objetos Ä Los datos compartidos son accedidos por segmentos de programa denominados secciones críticas (que deben estar protegidas) © José A. Gil 9
Granularidad de la consistencia Ä Tamaño de grano (determinado por el diseñador) m palabra m bloque m página l pequeña l grande m objeto m segmento Ä Implementaciones Hw ~ grano pequeño m palabra, bloque o página pequeña Ä Implementaciones Sw ~ grano grande m página grande, objeto o segmento Ä Implementaciones híbridas ~ grano mediano m página pequeña o grande © José A. Gil 10
Algoritmos de acceso Ä SRSW (single reader / single writer) m Un solo nodo tiene permiso de lectura en un periodo de tiempo y sólo un nodo tiene permiso de escritura en ese mismo periodo l Dos réplicas l En sistemas con dos nodos ~ productor consumidor. l En sistemas con más nodos el algoritmo de gestión debe permitir la migración. Ä MRSW (multiple reader / single writer) m Varios nodos tienen permiso de lectura en un periodo de tiempo y sólo un nodo tiene permiso de escritura en un periodo de tiempo. l Múltiples réplicas l No es necesaria la migración en lectura. l Migración de escritura necesaria. © José A. Gil 11
Algoritmos de acceso Ä MRMW (multiple reader / multiple writer) m Varios nodos tienen permiso de lectura y escritura en un periodo de tiempo. l Múltiples réplicas l Es necesario un mecanismo (protocolo) para mantener la consistencia de los datos © José A. Gil 12
Gestión de la propiedad Ä Cada unidad de consistencia (grano) debe tener un nodo "home" responsable de la gestión de propiedad de esa unidad. Ä Una unidad de consistencia puede ser poseída por varios nodos en distintos intervalos de tiempo. Ä El mecanismo de gestión puede ser centralizado o distribuido. © José A. Gil 13
Protocolos de consistencia Ä Al haber varias réplicas es necesario mantener la consistencia. Ä Los protocolos se basan en una de estas políticas: m actualización m invalidación © José A. Gil m Restringidos l Estricta l Secuencial m Relajados l l l l l Procesador Débil (weak) Liberación (release) Perezoso (lazy) Liberación perezosa (lazy release) Entrada (entry) AURC Ámbito (scope) Generalizada (generalized) Necesitan primitivas de sincronización Ä El modelo de consistencia determina CUANDO se enteran los nodos de los cambios de valor de las variables. Ä Cuanto más relajado el modelo más difícil la programación, pero mejores prestaciones. Ä Modelos de consistencia 14
Clasificación de los sistemas DSM Ä Criterio: nivel de implementación DSM 1. Hardware 2. Software 2. 1. El sistema operativo 2. 1. 1. Dentro del núcleo 2. 1. 2. Fuera del núcleo 2. 2. Biblioteca de rutinas 2. 3. Primitivas insertadas por el compilador 3. Combinación de hardware/software © José A. Gil Ä Parámetros: 1. Conf. Arquitectónica 1. 1. Configuración del cluster (num. Procesadores, mem. Compartida, mem. Cache, niveles de cache) 1. 2. Red de interconexión (jerarquías de bus, anillo, malla, hipercubo, LAN específica etc. ) 2. Organización de los datos compartidos 2. 1. Estructura de datos (no estructurados en objetos, tipos, etc. ) 2. 2 Grano de coherencia (palabra, bloque de cache, página, estructura de datos, etc. ) 15
Clasificación de los sistemas DSM Ä Segundo criterio: algoritmo de DSM 1. SRSW (single reader / single writer) 1. 1. Sin migración 1. 2. Con migración 2. MRSW (multiple reader / single writer) 3. MRMW (multiple reader / multiple writer) Ä Replicación: pueden existir copias múltiples de los mismos datos Ä Migración: una sola copia de datos que migra cuando se accede, si no es local © José A. Gil Ä Parámetros: m 1. Responsabilidad de gestión de DSM (centralizada, distribuida/fija, distribuida/dinámica) m 2. Modelo de consistencia (strict, sequential, processor, weak, release, lazy release, entry, etc. ) m 3. Política de coherencia (write-invalidate, writeupdate, type-specific, etc. ) 16
Protocolos de consistencia Ä Cronológicamente, las implementaciones relajadas software son anteriores. m La idea básica detrás de DSM software, a menudo llamado SVM (Memoria Virtual Compartida), es emular un protocolo de coherencia de cache de granularidad de página en lugar de los bloques de cache. m En esas condiciones (granularidad más basta), el mayor problemas es la falsa compartición. l la falsa compartición aparece cuando dos procesadores semánticamente no relacionados comparten la misma página (accediendo datos no relacionado que están en la misma página), y uno de ellos escribe sus datos. l el uso de consistencia relajada permite al sistema demorar la actividad de coherencia desde el instante de modificación al instante del próximo punto de sincronización (liberación, adquisición o ambos). Posponer la actividad de coherencia significa que puede que la actualización/invalidación no ocurra. © José A. Gil 17
Protocolos de consistencia Ä Consistencia estricta m TODOS los nodos se enteran INSTANTANEAMENTE de los cambios (solo modelo teórico). Ä Consistencia secuencial m El flujo particular de acceso y el flujo global de acceso que ve cada uno de los nodos son los mismos en todos los nodos. Ä Consistencia de procesador m El flujo particular de acceso que ve cada uno de los nodos es el mismo en todos los nodos. m El flujo global de acceso que ve cada uno de los nodos puede ser distinto. © José A. Gil 18
Protocolos de consistencia Ä Consistencia débil (weak) m Necesita puntos de sincronización (acquire - release) que delimiten las secciones críticas. m No se mantiene la consistencia fuera de las secciones críticas. m La consistencia se mantiene en ambos puntos de sincronización. m El código no puede continuar hasta que se establezca la consistencia en el punto de sincronización. m Los puntos de sincronización siguen las reglas de la consistencia secuencial. (todos los nodos ven el mismo orden global de accesos). © José A. Gil 19
Protocolos de consistencia Ä Consistencia de liberación (release) m La consistencia de memoria solamente se establece en los puntos de liberación. m Los puntos de liberación siguen un modelo de consistencia de procesador. m En cada punto de liberación se actualizan el resto de los procesadores/procesos con los cambios de las variables. l Esto genera tráfico potencialmente innecesario que puede tener un impacto negativo en la velocidad de ejecución de la aplicación. © José A. Gil 20
Protocolos de consistencia Ä Release Consistency m Dash (hw) m Munin (sw) © José A. Gil 21
Protocolos de consistencia Ä Liberación perezosa (lazy release) m La consistencia de memoria sólo tiene que ser establecida en el punto de la siguiente adquisición l El tráfico incluirá sólo las variables actualizadas que podrían usarse por la sección crítica de código que está a punto de empezar. m Se necesitará más espacio de "buffering" en cada procesador, para guardar las variables actualizadas hasta el comienzo de las siguientes secciones críticas. l Notese que algunas de las variables actualizadas no se usarán en la siguiente sección crítica. Sin embargo, esas variables contribuirán al tráfico (porque podrían ser usadas). © José A. Gil 22
Protocolos de consistencia Ä Lazy Release Consistency m Tread. Marks (sw) l Protocolo de escritor múltiple que usa invalidación. P 1 W(x) REL n Cada escritor guarda todos los cambios (diff) que hace en todas las páginas compartidas, desde el último punto de acquire. n En el siguiente punto de acquire, se envían write notices que invalidan las páginas modificadas. n En el primer acceso a una página invalidada, se recogen los diffs y se aplican en el orden causal apropiado, para reconstruir la página coherentemente. t ACQ P 2 x fallo(x) diff REL W(x) t x ACQ P 3 fallo(x) diff W(x) REL t ACQ P 4 © José A. Gil x fallo(x) diff R(x) REL t 23
Tread. Marks (estados y fallos) Ä Estados: m UNMAPPED l Páginas compartidas que no están en ese procesador m READ-ONLY l Protegida para lectura m READ-WRITE l Protegida para escritura m INVALID l Otro procesador ha escrito en ella © José A. Gil Ä Tipos de Fallos de Página m cold_miss l la primera vez que un procesador que no es el manager accede a ella m coherence_miss l acceso a una página invalidada m protection_fault l acceso de ESCRITURA a una página protegida para lectura 24
Tread. Marks (gestor de fallos) if ( p READ-ONLY ) then Allocate twin Change protection to READ-WRITE else if ( cold_miss) then get copy from manager if ( write notices ) then Retrieve diffs if ( write miss ) then Allocate twin Change protection to READ-WRITE else Change protection to READ-ONLY © José A. Gil 25
Tread. Marks (diagrama de estados) UNMAPPED READ FAULT WRITE FAULT READ-ONLY READ-WRITE DIFF CREATE READ FAULT WRITE NOTICE INVALID © José A. Gil Los WRITE FALUT generan TWIN Los DIFF CREATE eliminan los TWIN 26
Tread. Marks (ejemplo de programa) © José A. Gil #include <stdio. h> #include "Tmk. h" struct shared { int sum; int turn; int* array; } *shared; main(int argc, char **argv) { int start, end, i, p; int array. Dim = 100; /* Read array size from command line */ { int c; extern char* optarg; while ((c = getopt(argc, argv, "d: ")) != -1) switch (c) { case 'd': array. Dim = atoi(optarg); break; } } Tmk_startup(argc, argv); . . . 27
Tread. Marks (ejemplo de programa). . . Tmk_startup(argc, argv); if (Tmk_proc_id == 0) { shared = (struct shared *) Tmk_malloc(sizeof(shared)); if (shared == NULL) Tmk_exit(-1); /* share common pointer with all procs */ Tmk_distribute(&shared, sizeof(shared)); shared->array = (int *) Tmk_malloc(array. Dim * sizeof(int)); if (shared->array == NULL) Tmk_exit(-1); shared->turn = 0; shared->sum = 0; } Tmk_barrier(0); . . . © José A. Gil 28
Tread. Marks (ejemplo de programa) . . . Tmk_barrier(0); /* Determine array range for each processor */ { int id 0 = Tmk_proc_id, id 1 = Tmk_proc_id+1; int per. Proc = array. Dim / Tmk_nprocs; int left. Over = array. Dim % Tmk_nprocs; start = id 0 * per. Proc + id 0 * left. Over / Tmk_nprocs; end = id 1 * per. Proc + id 1 * left. Over / Tmk_nprocs; } for (i = start; i < end; i++) shared->array[i] = i; Tmk_barrier(0); . . . © José A. Gil 29
Tread. Marks (ejemplo de programa) . . . Tmk_barrier(0); /* Print array elements, in the natural output order */ for (p = 0; p < Tmk_nprocs; p++) { if (shared->turn == Tmk_proc_id) { for (i = start; i < end; i++) printf("%d: %dn", i, shared->array[i]); shared->turn++; } Tmk_barrier(0); }. . . © José A. Gil 30
Tread. Marks (ejemplo de programa). . . Tmk_barrier(0); } /* Compute local sum, then add to global sum */ { int my. Sum = 0; for (i = start; i < end; i++) my. Sum += shared->array[i]; Tmk_lock_acquire(0); shared->sum += my. Sum; Tmk_lock_release(0); } if (Tmk_proc_id == 0) { Tmk_free(shared->array); Tmk_free(shared); printf("Sum is %dn", shared->sum); } Tmk_exit(0); } © José A. Gil 31
Protocolos de consistencia Ä Entrada (entry) m Las variables compartidas (o grupo de variables compartidas) están protegidas por una variable de sincronización (una sección crítica está limitada por un par de accesos a la variable de sincronización). m Se pasarán las variables actualizadas por la red cuando sean absolutamente necesarias para las siguientes secciones críticas. m Semejante aproximación lleva a prestaciones potencialmente mejores. Sin embargo, las prestaciones concretas dependen de los detalles de la aplicación. © José A. Gil 32
Protocolos de consistencia Ä Entry consistency m Midway (sw) l Protocolo de escritor único que usa actualización n Entry consistency garantiza que los datos compartidos sólo se hacen consistentes cuando el procesador adquiere un objeto de sincronización. n Las ventajas de la consistencia de entrada pueden ser difíciles de obtener con un esfuerzo limitado en la programación n Por consiguiente, además de entry consistency, Midway soporta también liberación y consistencia del procesador. © José A. Gil 33
Protocolos de consistencia Ä Automatic Update Release Consistency (AURC) m SHRIMP (Scalable High-performance Really Inexpensive Multi-Processor) l El mecanismo de actualización hardware funciona punto l Cuando un nodo escribe, sólo se actualiza un nodo remoto (el home). l El nodo home es aquel que escribió primero en la página. l En los puntos de acquire se envía un mensaje al último propietario del lock (a través del home del lock). l El nodo adquisitor obtiene los "write notices" junto con el lock. n Los "write notices" indican todas las páginas que fueron actualizadas en el pasado de ese acquire de acuerdo con el orden parcial sucedió-primero. l Las páginas indicadas en el "write notice" son invalidadas, a menos que las versiones locales sean posteriores. l Cuando una página falla se envía una petición al home indicando la versión. © José A. Gil 34
Protocolos de consistencia Ä Automatic Update Release Consistency (AURC) m Cont. l El home mantiene el "copy set" (lista de nodos que comparten la página) y el "vector de versiones" actualizado (que locks escribieron en una determinada versión de la página). l Cada nodo mantiene una copia del elemento del vector de versiones que le atañe. Relacionado con las páginas replicadas en ese nodo. l Cuando al home le llega una petición de página (por un fallo remoto). n Si tiene al menos la versión requerida: contesta. n Si no: espera hasta conseguir la versión o posterior. © José A. Gil 35
Protocolos de consistencia Ä Automatic Update Release Consistency (AURC) m Cont. l Cuando llega al nodo la página que ha fallado se protege para escritura y se despierta al proceso que generó el fallo. l La primera escritura en la página después del acquire generará un fallo de escritura, que se utilizará para añadir la página a la "lista de actualizaciones" y desprotegerla. l Cada escritura es realizada sobre la copia local y propagada (hw) al home. l El resto de nodos serán actualizados cuando adquieran el lock y contacten con el home para obtener la última actualización de la página l En el punto de release el nodo incrementa su timestamp local y lo envía a todos los homes de las páginas de su "lista de actualizaciones" para que actualicen el vector de versiones, al mismo tiempo que se vacían los enlaces entre el nodo y los homes. Se protegen para escritura todas las páginas y se vacía la "lista de actualizaciones". © José A. Gil 36
Protocolos de consistencia Ä Automatic Update Release Consistency (AURC) l Copyset-2. comunicación punto a punto hardware entre el nodo de escritura y el nodo dueño de la página escrita l Copyset-N. Modelo de comunicaciones más general. ACQ P 1 t Au. Up P 2 R(x) ACQ W(x) x Flush Copy 1 REL t P 3 Copy 2 x t ACQ © José A. Gil REL 37
Protocolos de consistencia Ä Automatic Update Release Consistency (AURC) ACQ P 1 P 2 Au. Up ACQ W(x) R(x) x t Flush Copy 1 REL x t P 3 Copy 2 t ACQ REL P 0 ACQ P 1 ACQ W (x) Rd. Ft t x R (x) C opy 1 R EL P 2 t P 3 C opy 2 . . . C opy N -1 x t ACQ © José A. Gil OW NER REL 38
Protocolos de consistencia Ä Scope consistency (Sc. C) m SHRIMP (Scalable High-performance Really Inexpensive Multi-Processor), idéntico a AURC excepto: l Noticias de escritura mantenidas por lock, no por procesador l El vector de actualización de versiones en el home incluye campos (para cada lock) indicando qué variables fueron escritas; esto se repite para cada versión de la página. l En la adquisición, el nodo recibe del que libera solo las noticias de escritura que corresponden al lock. l Invalidación de páginas (igual que LRC/AURC). Cuando falla una página se trae del home (igual que AURC). l No se consulta al home en el acquire, sino cuando se invoca la variable (como en ENTRY) l La actividad de invocar una variable se relaciona con la página entera (diferencia con ENTRY). l Cada nodo mantiene una lista de listas de actualizaciones, una por cada lock (scope) abierto © José A. Gil 39
Protocolos de consistencia Ä Scope consistency (Sc. C) m Cont. l En el release el procesador incrementa su timestamp y el número de época del lock (el núm. de época se utiliza para determinar qué write notices enviar al siguiente acquire). l En tiempo de barrera se actualizan todas las write notices desde la última barrera (scope global). Lo que asegura que cuando se alcanza la barrera todo el espacio de direcciones se hace coherente. © José A. Gil 40
Protocolos de consistencia Ä Implementaciones DSM (hw-mayormente vs sw-mayormente ): © José A. Gil 41
DASH Ä Origen y Entorno m LENOSKI + LAUDON + GHARACHORLOO + WEBER + GUPTA + HENNESSY + HOROWITZ + LAM m Universidad de Stanford Ä El sistema: m nodo l SG 4 D/340 (4 Proc. , 2 -niveles cache local, memoria) l + tarjetas (controladora de directorio, interface de la red) m dos mallas 2 -D wormhole (petición + respuesta) m prototipo: 16 nodos m memoria compartido particionada m protocolo de coherencia cache distribuido por directorio Ä Referencia: m Lenoski, D. , et al. , "The Stanford DASH Multiprocessor, " IEEE Computer, Vol. 25, No. 3, March 1992, pp. 63 -79. © José A. Gil 42
DASH Ä Memoria distribuída con un solo espacio de dirección y un protocolo de coherencia de cache basado en directorio Ä Granularidad: bloque de cache (16 bytes) Ä Cada bloque tiene su home cluster: m el lugar físico m + entrada de directorio correspondiente © José A. Gil 43
DASH Ä Jerarquía de memoria: 4 niveles l 1. el cache de procesador l 2. las caches de otros procesadores del cluster local l 3. el cluster de home l 4. el cluster remoto Ä Protocolo de coherencia m Directorio distribuido completamente mapeado m Basado en invalidación Ä Entrada del directorio: m vector de bits de presencia + bit de sucio + bits de estado Ä Estados: m uncached: no cacheado por ningún otro cluster m shared: copias cacheadas no-modificadas m dirty: modificada la copia en una sola cache de algún cluster © José A. Gil 44
DASH Ä Operación de lectura: m Si no se satisface dentro del cluster l la petición se envía al directorio home m Si el bloque está en estado SHARED o UNCACHED l la petición se satisface por el cluster home l Si el estado era UNCACHED se cambia a SHARED. m Si el bloque está en estado DIRTY l la petición se reenvía al cluster remoto l la petición se satisface por el cluster remoto l se envía un mensaje de escritura al cluster home l el cluster home actualiza el estado a shared © José A. Gil 45
DASH Ä Operación de escritura: m Petición de lectura exclusiva al cluster home m Si el bloque está SHARED l El cluster home satisface la petición l El cluster home cambia el estado a DIRTY l El cluster home envía invalidaciones a las copias compartidas l Los clusters en sahed envían reconocimientos de invalidación al cluster que hizo la petición m Si el bloque está DIRTY l El cluster home retransmite la petición al cluster remoto l El cluster remoto satisface la petición. © José A. Gil 46
DASH Ä Diagrama de bloques de las tarjetas Respuestas a clusters Y ± 1 Peticiones a clusters Y ± 1 Respuestas a clusters X ± 1 Peticiones a clusters X ± 1 Encaminador Rply dimensión Y Encaminador Rply dimensión X Directory Controller (DC) board Reply Controller (RC) • Remote Access Cache (RAC) almacena el estado de las peticiones de memoria pendientes y las respuestas remotas • Contadores de invalidación por procesador • la RAC husmea en el bus Pseudo-CPU (PCPU) • Retranmite las peticiones remotas al MPbus • Genera invalidaciones de líneas de cache y bloqueo de premisos Directory Controller (DC) • Directorio DRAM • Retranmite las peticiones locales a clusters remotos • Responde petic. remotas • Responde al Mpbus con información del directorio • Almacena bloqueos y colas de bloqueos Monitor de Prestaciones • Cuentas, distribuciones y trazas del bus, red y eventos internos. Mpbus Direcciones, Control y Datos © José A. Gil 47
DASH Ä Petición de lectura de un bloque DIRTY Cluster Local • Una CPU genera una lectura en el bus y es forzada a reintentar • Se genera una nueva entrada en la RAC • DC envía una Read-Req al home • RC obtiene la Read-Rply y libera la CPU • La CPU reintenta la lectura y la RAC responde con los datos Read-Rply al local 3 a Read-Req al home 1 Cluster Home • La PCPU genera una lectura en el bus • La entrada en el directorio está en DIRTY • DC retransmite una Read-Req al cluster dirty • La PCPU genera Sharing-Writeback en el bus • DC actualiza la entrada del directorio al estado shared 3 b Sharing-Writeback al home Cluster Dirty Read-Req al dirty 2 • La PCPU genera una lectura en el bus • La cache dirty responde con los datos • DC envía una Read-Rply al cluster local • DC envía una Sharing-Writeback al cluster home © José A. Gil 48
DASH Ä Petición de escritura de un bloque SHARED Cluster Local • El buffer de escritura de la CPU genera una lectura-exclusiva en el bus y es forzado a reintentar • Se genera una nueva entrada en la RAC • DC envía una Read-Ex-Req al home • RC recibe Read-Ex-Rply con datos y cuenta de invalidación y libera la CPU • El buffer reintenta la lectura-exclusiva y el RAC contesta con los datos • El buffer reintenta la escritura • La cuenta de inv. de la entrada de la RAC se decrementa a cada Inv-Ack • Cuando la cuenta llega a 0 se libera la entrada de la RAC 3 1: n Inv-Ack al local © José A. Gil Read-Ex. Req al home Read-Ex-Req 1 Cluster Home 2 a Read-EXRply al local Clusters Remotos • La PCPU genera una lectura-excl en el bus • La entrada en el directorio está en SHARED • DC envía una Read-Ex-Rply con la cuenta de invalidación al cluster local • DC envía una Inv-Req a los cluster shared • DC actualiza el estado a DIRTY 2 b 1: n Inv-Req a los shared • La PCPU genera una lectura-excl. en el bus para • La PCPU lectura-excl. en el bus para invalidar lasgenera copias una compartidas • La PCPU genera una lectura-excl. en el bus para invalidar las copias • DC envía una Inv-Ackcompartidas al cluster local • DC envía una Inv-Ack al cluster local 49
DIPC: semáforos Ä Primitivas de gestión de semáforos m Declaración (creación, apertura de uno existente, . . . ) l semget (. . . ) m Control (inicialización, consulta, destrucción, . . . ) l semctl (. . . ) m Operaciones l semop (. . . ) Ä Includes necesarios: m # include <sys/types. h> m # include <sys/ipc. h> m # include <sys/sem. h> © José A. Gil 50
DIPC: semget Ä int semget ( key_t key, int nsems, int semflg ) m Parámetros n n n key: clave de acceso al conjunto de semáforos nsems: num. de semáforos en el conjunto semflg: flags de creación m Retorna: n un identificador del conjunto de semáforos o error si negativo m Ejemplo: #ifdef __GLIBC__ #define IPC_DIPC 00010000 /*make it distributed*/ #endif #define SEM_KEY 31 #define SEM_MODE (IPC_DIPC | IPC_EXCL | 0777). . . semid = semget(SEM_KEY, 2, SEM_MODE | IPC_CREAT); if(semid < 0) { fprintf(stderr, "semget() failed BECAUSE %sn", strerror(errno)); exit(-1); } © José A. Gil 51
DIPC: semctl Ä int semctl (int semid, int semnum, int cmd, union semun arg) m Parámetros n n semid: identificador del conjunto de semáforos semnum : num. del semáforo en el conjunto empezando por 0 cmd: orden arg: argumentos de la orden m Retorna: n resultado de la operación o error si negativo m Argumentos: #if !defined(__GNU_LIBRARY__) || defined(_SEMUN_UNDEFINED) union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; #endif © José A. Gil 52
DIPC: semctl Ä int semctl (int semid, int semnum, int cmd, union semun arg) m Ordenes: l cmd = IPC_STAT n Copia en arg. buf la estructura completa del conjunto l cmd = IPC_SET n Copia de arg. buf la estructura completa en el conjunto l cmd = IPC_RMID n Destruye el semáforo y despierta procesos (necesita permisos) l cmd = GETALL n Retorna en arg. array los valores de todos los semáforos (semval) l cmd = GETNCTN n Retorna un int con el número de procesos esperando que se incremente semval del semáforo semnum. l cmd = GETPID n Retorna un int con el identificador del último proceso que ejecutó un semop sobre el semáforo semnum. © José A. Gil 53
DIPC: semctl Ä int semctl (int semid, int semnum, int cmd, union semun arg) m Ordenes: l cmd = GETVAL n Retorna un int con el valor de semval del semáforo semnum. l cmd = GETZCNT n Retorna un int con el número de procesos esperando que semval del semáforo semnum tome el valor cero. l cmd = SETALL n Posiciona los valores de los semáforos de acuerdo con arg. array, los procesos que esperan "pueden" ser despertados. l cmd = SETVAL n Posiciona semval del semáforo semnum de acuerdo con arg. val, los procesos que esperan "pueden" ser despertados. © José A. Gil 54
DIPC: semctl Ä int semctl (int semid, int semnum, int cmd, union semun arg) m Ejemplo: unsigned short seminit[2]; . . . seminit[0] = seminit[1] = 0; if(semctl(semid, 0, SETALL, (union semun) seminit) < 0) { fprintf(stderr, "can't initialize the semaphores BECAUSE %sn", strerror(errno)); exit(-1); } © José A. Gil 55
DIPC: semop Ä int semop (int semid, struct sembuf *sops, unsigned nsops) m Parámetros l semid: identificador del conjunto de semáforos l sops: vector de operaciones empezando por 0 l nsops: num. de operaciones a realizar m Retorna: l resultado de la operación o error si negativo m Cada elemento del struct sembuf incluye: l short sem_num; /* semaphore number: 0 = first */ l short sem_op; /* semaphore operation */ l short sem_flg; /* operation flags */ © José A. Gil 56
DIPC: semop Ä int semop (int semid, struct sembuf *sops, unsigned nsops) m Operaciones l Si sem_op > 0 n semval = semval + sem_op l Si sem_op < 0 n Si semval >= abs(sem_op) s semval = semval - abs(sem_op) n Si no s semncnt = semncnt +1 s dormir hasta semval >= abs(sem_op) s semncnt = semncnt -1 s semval = semval - abs(sem_op) l Si sem_op = 0 n Si semval <> 0 s semzcnt = semzcnt +1 s dormir hasta semval = 0 s semzcnt = semzcnt -1 © José A. Gil 57
DIPC: semop Ä int semop (int semid, struct sembuf *sops, unsigned nsops) m Flags: l SEM_UNDO: la operación será deshecha cuando el proceso haga exit. l IPC_NOWAIT: el proceso no se esperará en el semáforo, en caso de que hubiera tenido que esperarse se devuelve el error EAGAIN m Ejemplo: struct sembuf sem[2]; . . . sem[1]. sem_num = 1; sem[1]. sem_op = -1; sem[1]. sem_flg = SEM_UNDO; if(semop(semid, &sem[1], 1) <0) { printf("mio: semop() failed BECAUSE %sn", strerror(errno)); exit(-1); } © José A. Gil 58
DIPC: mensajes Ä Primitivas de gestión de mensajes m Declaración (creación, apertura de uno existente, . . . ) l msgget (. . . ) m Control (inicialización, consulta, destrucción, . . . ) l msgctl (. . . ) m Operaciones l msgsnd (. . . ) l msgrcv (. . . ) Ä Includes necesarios: m # include <sys/types. h> m # include <sys/ipc. h> m # include <sys/sem. h> © José A. Gil 59
DIPC: msgget Ä int msgget ( key_t key, int msgflg ) m Parámetros n key: clave de acceso a la cola de mensajes n msgflg: flags de creación m Retorna: n un identificador de la cola de mensajes o error si negativo m Ejemplo: #ifdef __GLIBC__ #define IPC_DIPC 00010000 /* make it distributed */ #endif #define MSG_KEY 40 #define MSG_MODE (IPC_DIPC | IPC_EXCL | 0777). . . msgid = msgget(MSG_KEY, MSG_MODE | IPC_CREAT); if(msgid < 0) { fprintf(stderr, "msgget() failed BECAUSE %sn", strerror(errno)); exit(20); } © José A. Gil 60
DIPC: msgctl Ä int msgctl (int msqid, int cmd, struct msqid_ds *buf) m Parámetros n n n msqid: identificador de la cola de mensajes cmd: orden buf: puntero a estructura de cola m Retorna: n error si negativo m Ordenes: l cmd = IPC_STAT n Copia en buf la estructura completa de la cola l cmd = IPC_SET n Copia de buf la estructura completa en la cola l cmd = IPC_RMID n Destruye la cola y su estructura y despierta procesos (necesita permisos) m Ejemplo: msgctl(msgid, IPC_RMID, NULL); © José A. Gil 61
DIPC: msgctl Ä int msgctl (int msqid, int cmd, struct msqid_ds *buf) m Estructura de la cola: struct msqid_ds { struct ipc_perm msg_perm; /*structure describing operation permission*/ struct msg *__msg_first; /*pointer to first message on queue*/ struct msg *__msg_last; /*pointer to last message on queue*/ __time_t msg_stime; /*time of last msgsnd command*/ __time_t msg_rtime; /*time of last msgrcv command*/ __time_t msg_ctime; /*time of last change*/ struct wait_queue *__wwait; /*? ? ? */ struct wait_queue *__rwait; /*? ? ? */ unsigned short int __msg_cbytes; /*current number of bytes on queue*/ unsigned short int msg_qnum; /*num of messages currently queued*/ unsigned short int msg_qbytes; /*max number of bytes allowed on queue*/ __ipc_pid_t msg_lspid; /*pid of last msgsnd()*/ __ipc_pid_t msg_lrpid; /*pid of last msgrcv()*/ }; © José A. Gil 62
DIPC: msgsnd Ä int msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg) m Parámetros l msqid: identificador de la cola de mensajes l msgp: puntero al buffer del mensaje l msgsz: tamaño del mensaje en bytes l msgflg: comportamiento de la llamada Si msgsz > msg_qbytes Si msgflg = IPC_NOWAIT retorna ERROR Sino espera hasta msgsz <= msg_qbytes m Retorna: l error si negativo m El struct msgbuf incluye: struct msgbuf { long mtype; char mtext[1]; © José A. Gil /* message type, must be > 0 */ /* message data */ }; 63
DIPC: msgsnd Ä int msgsnd (int msqid, struct msgbuf *msgp, int msgsz, int msgflg) m Ejemplo: #define MSG_TYPE 10 #define MSG_SIZE 512 struct message { long mtype; char mtext[MSG_SIZE]; }; struct message mess; . . . mess. mtype = MSG_TYPE; /* not necessary here */ strcpy(mess. mtext, "Hello, Distributed Programming!"); if(msgsnd(msgid, (struct msgbuf *)&mess, sizeof(mess. mtext), 0) < 0) { fprintf(stderr, "msgsnd() failed BECAUSE %sn", strerror(errno)); exit(20); } © José A. Gil 64
- Slides: 65