SCK sck_srv_new(INT32 port) { _SCK* s = malloc(sizeof(_SCK)); s->mod = SKSERVER; s->fnc.connect = NULL; s->fnc.disconnect = NULL; s->fnc.accept = NULL; s->fnc.incoming = NULL; s->fnc.eerr = NULL; s->fnc.endsend = NULL; s->arg.autofree = FALSE; s->arg.argfree = NULL; s->arg.arg = NULL; s->buf.buf = malloc(SCK_BUFFER_SIZE); s->buf.mode = PKDEFAULT; s->buf.rsz = SCK_BUFFER_SIZE; memset(&s->inf.adr,0, sizeof(struct sockaddr_in)); s->inf.adr.sin_family = AF_INET; s->inf.adr.sin_port = htons(port); s->inf.adr.sin_addr.s_addr = htonl(INADDR_ANY); if ( (s->h = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP)) < 0 ) {free(s);return NULL;} INT32 flag_ok; setsockopt(s->h,SOL_SOCKET,SO_REUSEADDR,(char *)&flag_ok,sizeof(flag_ok)); if ( bind(s->h,(struct sockaddr *)(&s->inf.adr),sizeof(struct sockaddr_in)) < 0 ) {close(s->h);free(s);return NULL;} s->th = thr_new(_sck_srv_run,0,0,0); return s; }
SCK sck_sc_new(SCK srv,HSCK h, INT32 port) { _SCK* s = malloc(sizeof(_SCK)); s->mod = SKSRV; s->fnc.connect = srv->fnc.connect; s->fnc.disconnect = srv->fnc.disconnect; s->fnc.accept = srv->fnc.accept; s->fnc.incoming = srv->fnc.incoming; s->fnc.eerr = srv->fnc.eerr; s->fnc.endsend = srv->fnc.endsend; s->arg.autofree = FALSE; s->arg.argfree = NULL; s->arg.arg = NULL; s->buf.buf = malloc(srv->buf.rsz); s->buf.mode = srv->buf.mode; s->buf.rsz = srv->buf.rsz; memset(&s->inf.adr,0, sizeof(struct sockaddr_in)); s->inf.adr.sin_family = AF_INET; s->inf.adr.sin_port = htons(port); s->h = h; _sck_add(srv,s); s->th = thr_new(_sck_sc_run,0,0,0); return s; }
SCK sck_cli_new(CHAR* ip,INT32 port) { _SCK* c = malloc(sizeof(_SCK)); c->mod = SKCLIENT; c->fnc.connect = NULL; c->fnc.disconnect = NULL; c->fnc.accept = NULL; c->fnc.incoming = NULL; c->fnc.eerr = NULL; c->fnc.endsend = NULL; c->arg.autofree = FALSE; c->arg.argfree = NULL; c->arg.arg = NULL; c->buf.buf = malloc(SCK_BUFFER_SIZE); c->buf.mode = PKDEFAULT; c->buf.rsz = SCK_BUFFER_SIZE; memset(&c->inf.adr,0, sizeof(struct sockaddr_in)); c->inf.adr.sin_family = AF_INET; c->inf.adr.sin_port = htons(port); c->inf.adr.sin_addr.s_addr = inet_addr(ip); if ( (c->h = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP)) < 0 ) {free(c);return NULL;} c->th = thr_new(_sck_cli_run,0,0,0); return c; }
void runtime·newosproc(M *mp, void *stk) { ThrParam param; Sigset oset; if(0){ runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n", stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp); } runtime·sigprocmask(&sigset_all, &oset); runtime·memclr((byte*)¶m, sizeof param); param.start_func = runtime·thr_start; param.arg = (byte*)mp; // NOTE(rsc): This code is confused. stackbase is the top of the stack // and is equal to stk. However, it's working, so I'm not changing it. param.stack_base = (void*)mp->g0->stackbase; param.stack_size = (byte*)stk - (byte*)mp->g0->stackbase; param.child_tid = (intptr*)&mp->procid; param.parent_tid = nil; param.tls_base = (void*)&mp->tls[0]; param.tls_size = sizeof mp->tls; mp->tls[0] = mp->id; // so 386 asm can find it runtime·thr_new(¶m, sizeof param); runtime·sigprocmask(&oset, nil); }
void runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void)) { ThrParam param; Sigset oset; USED(fn); // thr_start assumes fn == mstart USED(gp); // thr_start assumes gp == mp->g0 if(0){ runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n", stk, mp, gp, fn, mp->id, mp->tls[0], &mp); } runtime·sigprocmask(&sigset_all, &oset); runtime·memclr((byte*)¶m, sizeof param); param.start_func = runtime·thr_start; param.arg = (byte*)mp; param.stack_base = (void*)gp->stackbase; param.stack_size = (byte*)stk - (byte*)gp->stackbase; param.child_tid = (intptr*)&mp->procid; param.parent_tid = nil; param.tls_base = (void*)&mp->tls[0]; param.tls_size = sizeof mp->tls; mp->tls[0] = mp->id; // so 386 asm can find it runtime·thr_new(¶m, sizeof param); runtime·sigprocmask(&oset, nil); }
kern_return_t MemO_start (kmod_info_t * ki, void * d) { thr_new((thr_callback_t)read_write, NULL, 0); uprintf("KEXT:%s has been loaded!\n", ki->name); printf("KEXT:%s has been loaded!\n", ki->name); return KERN_SUCCESS; }
int _pthread_create(pthread_t * thread, const pthread_attr_t * attr, void *(*start_routine) (void *), void *arg) { struct pthread *curthread, *new_thread; struct thr_param param; struct sched_param sched_param; struct rtprio rtp; sigset_t set, oset; cpuset_t *cpusetp; int i, cpusetsize, create_suspended, locked, old_stack_prot, ret; cpusetp = NULL; ret = cpusetsize = 0; _thr_check_init(); /* * Tell libc and others now they need lock to protect their data. */ if (_thr_isthreaded() == 0) { _malloc_first_thread(); if (_thr_setthreaded(1)) return (EAGAIN); } curthread = _get_curthread(); if ((new_thread = _thr_alloc(curthread)) == NULL) return (EAGAIN); memset(¶m, 0, sizeof(param)); if (attr == NULL || *attr == NULL) /* Use the default thread attributes: */ new_thread->attr = _pthread_attr_default; else { new_thread->attr = *(*attr); cpusetp = new_thread->attr.cpuset; cpusetsize = new_thread->attr.cpusetsize; new_thread->attr.cpuset = NULL; new_thread->attr.cpusetsize = 0; } if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { /* inherit scheduling contention scope */ if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; else new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; new_thread->attr.prio = curthread->attr.prio; new_thread->attr.sched_policy = curthread->attr.sched_policy; } new_thread->tid = TID_TERMINATED; old_stack_prot = _rtld_get_stack_prot(); if (create_stack(&new_thread->attr) != 0) { /* Insufficient memory to create a stack: */ _thr_free(curthread, new_thread); return (EAGAIN); } /* * Write a magic value to the thread structure * to help identify valid ones: */ new_thread->magic = THR_MAGIC; new_thread->start_routine = start_routine; new_thread->arg = arg; new_thread->cancel_enable = 1; new_thread->cancel_async = 0; /* Initialize the mutex queue: */ for (i = 0; i < TMQ_NITEMS; i++) TAILQ_INIT(&new_thread->mq[i]); /* Initialise hooks in the thread structure: */ if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { new_thread->flags = THR_FLAGS_NEED_SUSPEND; create_suspended = 1; } else { create_suspended = 0; } new_thread->state = PS_RUNNING; if (new_thread->attr.flags & PTHREAD_CREATE_DETACHED) new_thread->flags |= THR_FLAGS_DETACHED; /* Add the new thread. */ new_thread->refcount = 1; _thr_link(curthread, new_thread); /* * Handle the race between __pthread_map_stacks_exec and * thread linkage. */ if (old_stack_prot != _rtld_get_stack_prot()) _thr_stack_fix_protection(new_thread); /* Return thread pointer eariler so that new thread can use it. */ (*thread) = new_thread; if (SHOULD_REPORT_EVENT(curthread, TD_CREATE) || cpusetp != NULL) { THR_THREAD_LOCK(curthread, new_thread); locked = 1; } else locked = 0; param.start_func = (void (*)(void *)) thread_start; param.arg = new_thread; param.stack_base = new_thread->attr.stackaddr_attr; param.stack_size = new_thread->attr.stacksize_attr; param.tls_base = (char *)new_thread->tcb; param.tls_size = sizeof(struct tcb); param.child_tid = &new_thread->tid; param.parent_tid = &new_thread->tid; param.flags = 0; if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) param.flags |= THR_SYSTEM_SCOPE; if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) param.rtp = NULL; else { sched_param.sched_priority = new_thread->attr.prio; _schedparam_to_rtp(new_thread->attr.sched_policy, &sched_param, &rtp); param.rtp = &rtp; } /* Schedule the new thread. */ if (create_suspended) { SIGFILLSET(set); SIGDELSET(set, SIGTRAP); __sys_sigprocmask(SIG_SETMASK, &set, &oset); new_thread->sigmask = oset; SIGDELSET(new_thread->sigmask, SIGCANCEL); } ret = thr_new(¶m, sizeof(param)); if (ret != 0) { ret = errno; /* * Translate EPROCLIM into well-known POSIX code EAGAIN. */ if (ret == EPROCLIM) ret = EAGAIN; } if (create_suspended) __sys_sigprocmask(SIG_SETMASK, &oset, NULL); if (ret != 0) { if (!locked) THR_THREAD_LOCK(curthread, new_thread); new_thread->state = PS_DEAD; new_thread->tid = TID_TERMINATED; new_thread->flags |= THR_FLAGS_DETACHED; new_thread->refcount--; if (new_thread->flags & THR_FLAGS_NEED_SUSPEND) { new_thread->cycle++; _thr_umtx_wake(&new_thread->cycle, INT_MAX, 0); } _thr_try_gc(curthread, new_thread); /* thread lock released */ atomic_add_int(&_thread_active_threads, -1); } else if (locked) { if (cpusetp != NULL) { if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(new_thread), cpusetsize, cpusetp)) { ret = errno; /* kill the new thread */ new_thread->force_exit = 1; new_thread->flags |= THR_FLAGS_DETACHED; _thr_try_gc(curthread, new_thread); /* thread lock released */ goto out; } } _thr_report_creation(curthread, new_thread); THR_THREAD_UNLOCK(curthread, new_thread); } out: if (ret) (*thread) = 0; return (ret); }