int shmat(struct proc *p, struct shmat_args *uap, user_addr_t *retval) { int error, i, flags; struct shmid_kernel *shmseg; struct shmmap_state *shmmap_s = NULL; struct shm_handle *shm_handle; mach_vm_address_t attach_va; /* attach address in/out */ mach_vm_size_t map_size; /* size of map entry */ mach_vm_size_t mapped_size; vm_prot_t prot; size_t size; kern_return_t rv; int shmat_ret; int vm_flags; shmat_ret = 0; AUDIT_ARG(svipc_id, uap->shmid); AUDIT_ARG(svipc_addr, uap->shmaddr); SYSV_SHM_SUBSYS_LOCK(); if ((shmat_ret = shminit())) { goto shmat_out; } shmmap_s = (struct shmmap_state *)p->vm_shm; if (shmmap_s == NULL) { /* lazily allocate the shm map */ int nsegs = shminfo.shmseg; if (nsegs <= 0) { shmat_ret = EMFILE; goto shmat_out; } /* +1 for the sentinel */ if (os_add_and_mul_overflow(nsegs, 1, sizeof(struct shmmap_state), &size)) { shmat_ret = ENOMEM; goto shmat_out; } MALLOC(shmmap_s, struct shmmap_state *, size, M_SHM, M_WAITOK | M_NULL); if (shmmap_s == NULL) { shmat_ret = ENOMEM; goto shmat_out; } /* initialize the entries */ for (i = 0; i < nsegs; i++) { shmmap_s[i].shmid = SHMID_UNALLOCATED; } shmmap_s[i].shmid = SHMID_SENTINEL; p->vm_shm = (caddr_t)shmmap_s; }
int shmdt(struct proc *p, struct shmdt_args *uap, int32_t *retval) { #if CONFIG_MACF struct shmid_kernel *shmsegptr; #endif struct shmmap_state *shmmap_s; int i; int shmdtret = 0; AUDIT_ARG(svipc_addr, uap->shmaddr); SYSV_SHM_SUBSYS_LOCK(); if ((shmdtret = shminit())) { goto shmdt_out; } shmmap_s = (struct shmmap_state *)p->vm_shm; if (shmmap_s == NULL) { shmdtret = EINVAL; goto shmdt_out; } for (; shmmap_s->shmid != SHMID_SENTINEL; shmmap_s++) { if (SHMID_IS_VALID(shmmap_s->shmid) && shmmap_s->va == (mach_vm_offset_t)uap->shmaddr) { break; } } if (!SHMID_IS_VALID(shmmap_s->shmid)) { shmdtret = EINVAL; goto shmdt_out; } #if CONFIG_MACF /* * XXX: It might be useful to move this into the shm_delete_mapping * function */ shmsegptr = &shmsegs[IPCID_TO_IX(shmmap_s->shmid)]; shmdtret = mac_sysvshm_check_shmdt(kauth_cred_get(), shmsegptr); if (shmdtret) goto shmdt_out; #endif i = shm_delete_mapping(p, shmmap_s, 1); if (i == 0) *retval = 0; shmdtret = i; shmdt_out: SYSV_SHM_SUBSYS_UNLOCK(); return shmdtret; }
int main(void) /* 服務程式 */ { struct exchange *shm; int producer_ok,consumer_ok,i; int shmid; char readbuf[BUFSIZ]; /* 建立訊號量consumer和producer */ consumer_ok = open_semaphore_set(key1, 1); producer_ok= open_semaphore_set(key2, 1); init_a_semaphore(consumer_ok, 0, 1); /* 禁止消費 */ init_a_semaphore(producer_ok, 0, 0); /* 容許生產 */ /* 獲得並連線名為"shared"的共享儲存段 */ shm = (struct exchange *)shminit(ftok("shared",0),&shmid); /* 從標准輸入讀資料並寫至共享儲存段 */ for ( i=0; ; i++ ) { /* 讀入資料 */ semaphore_P(consumer_ok); /* 等待客戶執行緒釋放共享儲存段 */ printf("Enter some text:"); fgets(readbuf,BUFSIZ,stdin); /* 填充共享儲存緩沖 */ shm->seq = i; sprintf(shm->buf, "%s",readbuf); semaphore_V(producer_ok); /* 容許客戶執行緒取資料 */ if (strncmp(readbuf, "end", 3) == 0 ) break; } semaphore_P(consumer_ok); /* 等待客戶執行緒消費完畢 */ /* 移除訊號量 */ rm_semaphore(producer_ok); rm_semaphore(consumer_ok); /* 分離並移除共享儲存段 */ shmdt(shm); shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL); exit(0); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // detect other processors lapicinit(); // interrupt controller seginit(); // segment descriptors picinit(); // disable pic ioapicinit(); // another interrupt controller consoleinit(); // console hardware uartinit(); // serial port pinit(); // process table shminit(); // shared memory tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); // finish this processor's setup }
int drawinit(int w, int h) { atexit(shmfree); if((display = XOpenDisplay(NULL)) == NULL){ fprintf(stderr, "cannot open display!\n"); return -1; } width = w > 0 ? w : 640; height = h > 0 ? h : 360; visual = DefaultVisual(display, 0); window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0, width, height, 1, 0, 0); if(visual->class != TrueColor){ fprintf(stderr, "Cannot handle non true color visual ...\n"); return -1; } shminit(); XSelectInput( display, window, EnterWindowMask| LeaveWindowMask| PointerMotionMask| KeyPressMask| KeyReleaseMask| ButtonPressMask| ButtonReleaseMask| ExposureMask| StructureNotifyMask| 0 ); XMapWindow(display, window); return XConnectionNumber(display); }
/* * drawevents2 calls flush to display anything that was drawn. */ static Input * drawevents2(int block, int *ninp) { static int flushing; if(!flushing){ if(screen.dirty){ drawflush(screen.r); flushing = 1; screen.dirty = 0; } ninputs = 0; } while((block && (flushing || ninputs == 0)) || XPending(display)){ XEvent ev; XNextEvent(display, &ev); switch(ev.type){ case MapNotify: case ReparentNotify: addredraw(); continue; case Expose: addredraw(); continue; case KeyPress: case KeyRelease: { XKeyEvent *ep = &ev.xkey; if(0)fprintf( stderr, "key %s %d (%x) '%c' at (%d,%d) state %x\n", ev.type == KeyPress ? "pressed" : "released", ep->keycode, ep->keycode, isprint(ep->keycode) ? ep->keycode : '.', ep->x, ep->y, ep->state ); u64int mod; KeySym keysym; int code; char keystr[8] = {0}; keysym = XLookupKeysym(ep, ep->state & (ShiftMask|LockMask)); if((code = keysym2ucs(keysym)) != -1) utf8encode(keystr, sizeof keystr-1, code); else keystr[0] = '\0'; switch(keysym){ case XK_Return: case XK_KP_Enter: strncpy(keystr, "\n", sizeof keystr-1); mod = KeyStr; break; case XK_Tab: case XK_KP_Tab: case XK_ISO_Left_Tab: strncpy(keystr, "\t", sizeof keystr-1); mod = KeyStr; break; case XK_Break: mod = KeyBreak; break; case XK_BackSpace: mod = KeyBackSpace; break; case XK_Down: mod = KeyDown; break; case XK_End: mod = KeyEnd; break; case XK_Home: mod = KeyHome; break; case XK_Left: mod = KeyLeft; break; case XK_Page_Down: mod = KeyPageDown; break; case XK_Page_Up: mod = KeyPageUp; break; case XK_Right: mod = KeyRight; break; case XK_Up: mod = KeyUp; break; case XK_Shift_L: case XK_Shift_R: mod = KeyShift; break; case XK_Control_L: case XK_Control_R: mod = KeyControl; break; case XK_Meta_L: case XK_Meta_R: mod = KeyMeta; /* mac command key */ break; case XK_Alt_L: case XK_Alt_R: mod = KeyAlt; break; case XK_Super_L: case XK_Super_R: fprintf(stderr, "super\n"); mod = KeySuper; break; case XK_Hyper_L: case XK_Hyper_R: fprintf(stderr, "hyper\n"); mod = KeyHyper; break; case XK_KP_Insert: case XK_Insert: mod = KeyIns; break; case XK_KP_Delete: case XK_Delete: mod = KeyDel; break; case XK_Caps_Lock: mod = KeyCapsLock; break; default: mod = 0; break; } addinput( 0, 0, keystr, mod, ev.type == KeyPress, ev.type == KeyRelease ); } continue; case ButtonPress: case ButtonRelease: { XButtonEvent *ep = &ev.xbutton; u64int mod; switch(ep->button){ case 0:case 1:case 2:case 3:case 4: case 5:case 6:case 7:case 9:case 10: mod = Mouse0 << ep->button; break; default: fprintf(stderr, "unsupported mouse button %d\n", ep->button); mod = 0; break; } if(mod != 0){ addinput( ep->x, ep->y, NULL, mod, ev.type == ButtonPress, ev.type == ButtonRelease ); } } continue; case EnterNotify: case LeaveNotify: fprintf(stderr, "enter/leave\n"); continue; case MotionNotify: if(input_prevmod != 0){ XMotionEvent *ep = &ev.xmotion; u64int m; if(0)fprintf( stderr, "motion at (%d,%d) state %x\n", ep->x, ep->y, ep->state ); for(m = Mouse0; m <= LastMouse; m <<= 1){ addinput( ep->x, ep->y, NULL, m, 0,0 ); } } continue; case ConfigureNotify: { XConfigureEvent *ce = &ev.xconfigure; if(ce->width != width || ce->height != height){ shmfree(); width = ce->width; height = ce->height; if(shminit() == -1){ *ninp = 0; return NULL; } addredraw(); } continue; } } if(ev.type == XShmGetEventBase(display) + ShmCompletion){ flushing = 0; if(animating){ addredraw(); } continue; } fprintf(stderr, "unknown xevent %d\n", ev.type); } if(!flushing && ninputs > 0){ *ninp = ninputs; return inputs; } *ninp = 0; return NULL; }