If you can't read please download the document
Upload
ahmed-mekkawy
View
1.194
Download
3
Embed Size (px)
DESCRIPTION
session 13 of the system programming course made by eglug
Citation preview
2. Outline
3. IPC Mechanisms So Far
4. Pipes
5. struct job *jp; struct nodelist *lp; int pipelen; int prevfd; int pip[2]; prevfd = -1; for (lp = n->npipe.cmdlist; lp; lp = lp->next) { ... pip[1] = -1; if (lp->next) { if (pipe(pip) < 0) { ... } } if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { ... if (pip[1] >= 0) { close(pip[0]); } if (prevfd > 0) { dup2(prevfd, 0); close(prevfd); } if (pip[1] > 1) { dup2(pip[1], 1); close(pip[1]); } /* Execute */ /* never returns */ } if (prevfd >= 0) close(prevfd); prevfd = pip[0]; close(pip[1]); } 6. FIFOs
7. SysV Generic
8. SysV Semaphores
9. Semaphore control
10. Semaphore Ops
11. SysV Messages
12. Msg Receival
13. SysV Shared Memory
14. static void ipcsyslog_init(void) { if (DEBUG) printf("shmget(%x, %d,...) ", (int)KEY_ID, G.shm_size); G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644); if (G.shmid == -1) { bb_perror_msg_and_die("shmget"); } G.shbuf = shmat(G.shmid, NULL, 0); if (G.shbuf == (void*) -1L) { /* shmat has bizarre error return */ bb_perror_msg_and_die("shmat"); } memset(G.shbuf, 0, G.shm_size); G.shbuf->size = G.shm_size - offsetof(struct shbuf_ds, data) - 1; /*G.shbuf->tail = 0;*/ // we'll trust the OS to set initial semval to 0 (let's hope) G.s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023); if (G.s_semid == -1) { if (errno == EEXIST) { G.s_semid = semget(KEY_ID, 2, 0); if (G.s_semid != -1) return; } bb_perror_msg_and_die("semget"); } } static void log_to_shmem(const char *msg, int len) { int old_tail, new_tail; if (semop(G.s_semid, G.SMwdn, 3) == -1) { bb_perror_msg_and_die("SMwdn"); } ... /* Circular buffer calculation */ memcpy(G.shbuf->data + old_tail, msg, k); if (semop(G.s_semid, G.SMwup, 1) == -1) { bb_perror_msg_and_die("SMwup"); } } static void ipcsyslog_cleanup(void) { if (G.shmid != -1) { shmdt(G.shbuf); } if (G.shmid != -1) { shmctl(G.shmid, IPC_RMID, NULL); } if (G.s_semid != -1) { semctl(G.s_semid, 0, IPC_RMID, 0); } } 15. POSIX Generic
16. POSIX Semaphores
17. Semaphore Ops
18. POSIX Message Queues
19. Mq Attributes
20. POSIX Shared Memory
21. Memory Mapping for Shared memory
22. POSIX shm example int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { char fn[32]; int fd = -1; struct shm_marker *marker; pa_random(&m->id, sizeof(m->id)); segment_name(fn, sizeof(fn), m->id); if ((fd = shm_open(fn, O_RDWR|O_CREAT|O_EXCL, mode & 0444)) < 0) { ... } m->size = size + PA_ALIGN(sizeof(struct shm_marker)); if (ftruncate(fd, m->size) < 0) { ...} if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { ... } marker = (struct shm_marker*) ((uint8_t*) m->ptr + m->size - PA_ALIGN(sizeof(struct shm_marker))); pa_atomic_store(&marker->pid, (int) getpid()); pa_atomic_store(&marker->marker, SHM_MARKER); ... m->do_unlink = 1; } void pa_shm_free(pa_shm *m) { ... if (munmap(m->ptr, m->size) < 0) pa_log("munmap() failed: %s", pa_cstrerror(errno)); if (m->do_unlink) { char fn[32]; segment_name(fn, sizeof(fn), m->id); if (shm_unlink(fn) < 0) pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno)); } ... memset(m, 0, sizeof(*m)); } struct shm_marker { pa_atomic_t marker; /* 0xbeefcafe */ pa_atomic_t pid; void *_reserverd1; void *_reserverd2; void *_reserverd3; void *_reserverd4; }; static char *segment_name(char *fn, size_t l, unsigned id) { pa_snprintf(fn, l, "/pulse-shm-%u", id); return fn; } 23. struct pa_semaphore { sem_t sem; }; pa_semaphore* pa_semaphore_new(unsigned value) { pa_semaphore *s; s = pa_xnew(pa_semaphore, 1); &s->sem, 0, value); return s; } void pa_semaphore_free(pa_semaphore *s) { sem_destroy(&s->sem) ; } void pa_semaphore_post(pa_semaphore *s) { sem_post(&s->sem) ; } void pa_semaphore_wait(pa_semaphore *s) { int ret; do { ret = sem_wait(&s->sem); } while (ret < 0 && errno == EINTR); } pa_mempool* pa_mempool_new(int shared) { pa_mempool *p; ... p = pa_xnew(pa_mempool, 1); p->semaphore = pa_semaphore_new(0); p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE); ... if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) { } ... return p; } void pa_mempool_free(pa_mempool *p) { ... pa_shm_free(&p->memory); ... pa_semaphore_free(p->semaphore); pa_xfree(p); } static void memblock_wait(pa_memblock *b) { if (pa_atomic_load(&b->n_acquired) > 0) { pa_atomic_inc(&b->please_signal); while (pa_atomic_load(&b->n_acquired) > 0) pa_semaphore_wait(b->pool->semaphore); pa_atomic_dec(&b->please_signal); } } void pa_memblock_release(pa_memblock *b) { int r; r = pa_atomic_dec(&b->n_acquired); pa_assert(r >= 1); if (r == 1 && pa_atomic_load(&b->please_signal)) pa_semaphore_post(b->pool->semaphore); }