void toi_init(int argc, char **argv) { gv_tbl = st_init_numtable(); Init_thread(); THREAD(cur_thr)->recv = main_thread(); if (THREAD(main_thread())->env_tbl) st_free_table(THREAD(main_thread())->env_tbl); THREAD(main_thread())->env_tbl = gv_tbl; Init_symbol(); Init_class(); /* have to call Init_thread() again */ Init_thread(); Init_kernel(); cself = cKernel; Init_numeric(); Init_float(); Init_integer(); Init_array(); Init_hash(); Init_string(); Init_iostream(); Init_exception(); toi_set_argv(argc, argv); Init_gc(); signal(SIGINT, handle_sigint); }
/* FIXME: incompatible with current design of soft-method-calling */ VALUE thread_schedule() { int i; VALUE th; /* don't increment round-robin count if in critical section */ if ( TEST(thr_crit) || (vector_length(thr_stk) <= 1) ) { if (!THREAD(cur_thr)->alive_p) thread_deadlock(); return cur_thr; } /* find the highest priority thread; lowest round-robin count otherwise */ for (i = 0; i < vector_length(thr_stk); i++) { th = (VALUE)vector_aref(thr_stk, i); if ( (THREAD(th)->prio > THREAD(cur_thr)->prio) || (!(THREAD(th)->prio < THREAD(cur_thr)->prio) && (THREAD(th)->cnt < THREAD(cur_thr)->cnt)) ) { if (THREAD(th)->alive_p) cur_thr = (VALUE)vector_aref(thr_stk, i); else THREAD(th)->cnt++; } } THREAD(cur_thr)->cnt++; return cur_thr; }
/* * ksched_start_irq_handler(irqn) * * Starts an IRQ handling thread, if an IRQ arrives for it. * * */ void ksched_start_irq_handler(irq_t irqn) { /* Is the IRQ in use? */ if (irq_handlers_s[irqn].tid == 0) return; /* Is it allready handled? */ if (irq_handlers_s[irqn].is_handling == 1) return; /* Handle it */ irq_handlers_s[irqn].is_handling = 1; /* Disable the IRQ (staying enabled if RTC-IRQ) */ if (irqn != 0) ksched_disable_irq(irqn); /* Handle the IRQ */ THREAD(irq_handlers_s[irqn].tid, THRTAB_THRSTAT_FLAGS) &= (~THRSTAT_IRQ); THREAD(irq_handlers_s[irqn].tid, THRTAB_THRSTAT_FLAGS) |= THRSTAT_IRQ_HANDLING; ksched_start_thread(&THREAD(irq_handlers_s[irqn].tid, 0)); /* Thread change */ ksched_change_thread = true; return; }
VALUE throw_exc(VALUE self, int argc, VALUE *argv) { /* argv[0] == VALUE string descrip; argv[1] == optional exception class being thrown (default `Exception') */ int i, len; VALUE buf, thr, ret, exc_type; VALUE exc; thr = cur_thr; exc = THREAD(thr)->excobj; while (!TEST(exc) && TEST(thr)) { thr = THREAD(thr)->up; if (TEST(thr)) exc = THREAD(thr)->excobj; else exc = Qnil; } if (!TEST(exc)) { if ( (argc > 0) && argv[0] && (TYPE(argv[0]) == T_STRING) ) fail(str2cstr(argv[0])); else fail("unhandled exception"); } if ((argc > 0) && (argv[0]) && TEST(argv[0])) EXCEPTION(exc)->strerror = argv[0]; else EXCEPTION(exc)->strerror = string_new("(details of exception unspecified)"); if (argc > 1) exc_type = argv[1]; else exc_type = cException; if (!TEST(exc) || !kind_of_p(exc, exc_type)) fail("uncaught exception"); if (TEST(EXCEPTION(exc)->rescue_thr)) { thr = cur_thr; cur_thr = EXCEPTION(exc)->rescue_thr; eval_stack( THREAD(EXCEPTION(exc)->rescue_thr)->stack ); ret = Qbreak; cur_thr = thr; } else { ret = THREAD(cur_thr)->last; cur_thr = EXCEPTION(exc)->thr; } return ret; }
void gwthread_wakeup_all(void) { long i; long our_thread = gwthread_self(); for (i = 0; i < THREADTABLE_SIZE; ++i) { if (THREAD(our_thread) != THREAD(i)) gwthread_wakeup(i); } }
VALUE thread_s_main() { VALUE thr; return (VALUE)vector_first(thr_stk); for (thr = cur_thr; TEST(thr); thr = THREAD(thr)->up) if (! TEST(THREAD(thr)->up) ) return thr; return thr; }
VALUE gc_s_run(VALUE self) { VALUE sav_cur, thr = cur_thr; sav_cur = cur_thr; while (thr) { vector_foreach(THREAD(thr)->obj_stk, object_refcount_check); thr = cur_thr = THREAD(thr)->up; } cur_thr = sav_cur; return Qnil; }
VALUE pop_scope() { VALUE tmp; vector_t *stk = thr_stk; VALUE thr; thr = (VALUE)vector_pop(stk); while ( (tmp = (VALUE)vector_pop(THREAD(thr)->obj_stk)) ) memdealloc(tmp); cur_thr = THREAD(thr)->up; return thr; }
/*----------------------------------------------------------------------------- * bgnsurface - allocate and initialize an o_surface structure * * Client: GL user *----------------------------------------------------------------------------- */ void NurbsTessellator::bgnsurface( long nuid ) { O_surface *o_surface = new(o_surfacePool) O_surface; o_surface->nuid = nuid; THREAD( do_bgnsurface, o_surface, do_freebgnsurface ); }
/*----------------------------------------------------------------------------- * bgncurve - allocate an initialize an o_curve structure * * Client: GL user *----------------------------------------------------------------------------- */ void NurbsTessellator::bgncurve( long nuid ) { O_curve *o_curve = new(o_curvePool) O_curve; o_curve->nuid = nuid; THREAD( do_bgncurve, o_curve, do_freebgncurve ); }
int object_refcount_down(void *ptr) { VALUE obj = (VALUE)ptr; if (BASIC(obj).refcount == GC_NEVER_FREE) return VECTOR_CONTINUE; else if (THREAD(cur_thr)->last == obj) return VECTOR_CONTINUE; else if (--(BASIC(obj).refcount) > 0) return VECTOR_CONTINUE; memdealloc(obj); vector_delete(THREAD(cur_thr)->obj_stk, (void*)obj); return VECTOR_DELETE; }
FB::variant ibrowserAPI::uninstallPackage(const std::string& fileName, const boost::optional<FB::JSObjectPtr>& pcb, F_ADD) { if(fileName.empty()) return false; THREAD(&ibrowserAPI::uninstallPackage,fileName,pcb); int ret=0; Callback *cb = new Callback(); cb->set("pcb",*pcb); cb->set("scb",*scb); cb->set("ecb",*ecb); while (INSTPROXY_E_OP_IN_PROGRESS == (ret = instproxy_uninstall(instproxy_client, fileName.c_str(), NULL, &ibrowserAPI::installCallback, (void*)cb))) { log("uninstallPackage %s sleep...",fileName.c_str()); sleep(1); } if(INSTPROXY_E_SUCCESS != ret) { ERRO("instproxy_uninstall"); } return true; }
FB::variant ibrowserAPI::getAppList(F_ADD) { THREAD(&ibrowserAPI::getAppList); char *xml_doc=NULL; uint32_t xml_length=0; plist_t node = NULL; plist_t client_opts = instproxy_client_options_new(); instproxy_client_options_add(client_opts, "ApplicationType", "User", NULL); if(INSTPROXY_E_SUCCESS != instproxy_browse(instproxy_client,client_opts,&node)) { ERRO("instproxy_browse"); } instproxy_client_options_free(client_opts); plist_to_xml(node, &xml_doc, &xml_length); plist_free(node); SUCC(xml_doc); return xml_doc; }
FB::variant ibrowserAPI::getDeviceInfo(const std::vector<std::string>& domains,F_ADD) { THREAD(&ibrowserAPI::getDeviceInfo, domains); std::vector<std::string> result; for(int i=0;i<domains.size();i++) { std::string domain = domains[i]; plist_t node = NULL; int ret = 0; if(LOCKDOWN_E_SUCCESS != (ret = lockdownd_get_value(lockdownd_client, domain.empty()?NULL:domain.c_str(), NULL, &node)) ) { ERRO("lockdownd_get_value"); } char *xml_doc=NULL; uint32_t xml_length; plist_to_xml(node, &xml_doc, &xml_length); plist_free(node); result.insert(result.end(),std::string(xml_doc)); free(xml_doc); } SUCC(result); return result; }
static VALUE get_current_exception_block() { VALUE ret = Qnil, thr = cur_thr; while (TEST(thr)) { //ret = (VALUE)vector_aref(THREAD(thr)->stack, THREAD(thr)->ip-1); ret = THREAD(thr)->excobj; if (TEST(ret) && (TYPE(ret) == T_EXCEPTION)) return ret; else thr = THREAD(thr)->up; } return Qnil; }
/* Allocate and fill a threadinfo structure for a new thread, and store * it in a free slot in the thread table. The thread table must already * be locked by the caller. Return the thread number chosen for this * thread. The caller must make sure that there is room in the table. */ static long fill_threadinfo(pthread_t id, const char *name, gwthread_func_t *func, struct threadinfo *ti) { int pipefds[2]; long first_try; gw_assert(active_threads < THREADTABLE_SIZE); /* initialize to default values */ ti->self = id; ti->name = name; ti->func = func; ti->pid = -1; ti->wakefd_recv = -1; ti->wakefd_send = -1; ti->joiners = NULL; ti->number = -1; if (pipe(pipefds) < 0) { error(errno, "cannot allocate wakeup pipe for new thread"); return -1; } ti->wakefd_recv = pipefds[0]; ti->wakefd_send = pipefds[1]; socket_set_blocking(ti->wakefd_recv, 0); socket_set_blocking(ti->wakefd_send, 0); /* Find a free table entry and claim it. */ first_try = next_threadnumber; do { ti->number = next_threadnumber++; /* Check if we looped all the way around the thread table. */ if (ti->number == first_try + THREADTABLE_SIZE) { error(0, "Cannot have more than %d active threads", THREADTABLE_SIZE); ti->number = -1; return -1; } } while (THREAD(ti->number) != NULL); THREAD(ti->number) = ti; active_threads++; return ti->number; }
/*----------------------------------------------------------------------------- * setnurbsproperty - * *----------------------------------------------------------------------------- */ void NurbsTessellator::setnurbsproperty( long tag, INREAL value ) { if( ! renderhints.isProperty( tag ) ) { do_nurbserror( 26 ); } else { Property *prop = new(propertyPool) Property( tag, value ); THREAD( do_setnurbsproperty, prop, do_freenurbsproperty ); } }
static struct thread *rr_alloc_thread(void) { struct rr_thread *thread = kmem_cache_alloc(rr_thread_cache); if (!thread) return 0; list_init(&thread->link); return THREAD(thread); }
int mm_mmap(struct message *msg) { /*printk("mm: mapping 0x%X bytes of memory to 0x%X, tid=%d\n", msg->arg[2], msg->arg[1], msg->tid);*/ msg->arg[0] = (u32_t) THREAD(msg->tid)->process->memory->mmap(msg->arg[1] & ~0xfff, msg->arg[2], msg->arg[1] & 0xfff, msg->arg[3], 0); msg->send_size = 0; return 1; }
int gwthread_cancel(long thread) { struct threadinfo *threadinfo; gw_assert(thread >= 0); threadinfo = THREAD(thread); if (threadinfo == NULL || threadinfo->number != thread) { return -1; } else { return pthread_cancel(threadinfo->self); } }
int mm_munmap(struct message *msg) { //printk("mm: unmapping 0x%X bytes from 0x%X, tid=%d\n", msg->arg[2], msg->arg[1], msg->tid); if (msg->arg[1] > USER_MEM_BASE) { msg->arg[0] = 1; THREAD(msg->tid)->process->memory->munmap(msg->arg[1], msg->arg[2]); } else msg->arg[0] = -1; msg->send_size = 0; return 1; }
FB::variant ibrowserAPI::uploadFile(const std::string& fileName, const boost::optional<FB::JSObjectPtr>& pcb, F_ADD) { if(fileName.empty()) return false; THREAD(&ibrowserAPI::uploadFile,fileName,pcb); const char *file_name=fileName.c_str(); char target_file[1024]; sprintf(target_file, "%s/%s",uploadFileDir.c_str(), basename((char *)file_name)); uint64_t target_file_handle = 0; if (AFC_E_SUCCESS != afc_file_open(afc_client, target_file, AFC_FOPEN_WRONLY, &target_file_handle)){ ERRO("afc_file_open error!"); } FILE *file_handle= fopen(file_name, "r"); if (!file_handle) { afc_remove_path(afc_client, target_file); ERRO("open file error!"); } off_t fileSize = 0; struct stat st; if (stat(file_name, &st) == 0) fileSize = st.st_size; static int read_buf_size = 1024; char read_buf[read_buf_size]; int bytes_read; uint32_t bytes_written = 0; uint32_t doneSize = 0; while((bytes_read = fread(read_buf, 1, read_buf_size, file_handle)) >0 ) { if (AFC_E_SUCCESS != afc_file_write(afc_client, target_file_handle, read_buf, bytes_read, &bytes_written) || bytes_read !=bytes_written) { ERRO("afc_file_write error!"); } memset(read_buf, 0, read_buf_size); doneSize = doneSize + bytes_read; if(pcb && fileSize > 0) (*pcb)->InvokeAsync("", FB::variant_list_of((double)doneSize/fileSize)); } SUCC(target_file); return target_file; }
thread_t* prio_sched_next_thread(struct sched_t* schd) { thread_t* toReturn = NULL; queue_t** schd_queue = SCHED_QUEUE(schd); int i = 0; while ((i<LOWEST_PRIO) && (queue_size(schd_queue[i]) == 0)) ++i; if (i < LOWEST_PRIO) toReturn = THREAD(queue_pop(schd_queue[i])); return toReturn; }
static struct thread *rr_next_thread(void) { DBG_ASSERT(local_preempt_disabled()); if (list_empty(&rr_active_list)) return 0; struct list_head *first = list_first(&rr_active_list); struct rr_thread *thread = LIST_ENTRY(first, struct rr_thread, link); list_del(&thread->link); return THREAD(thread); }
/*----------------------------------------------------------------------------- * nurbssurface - * * Client: User routine *----------------------------------------------------------------------------- */ void NurbsTessellator::nurbssurface( long sknot_count, /* number of s knots */ INREAL sknot[], /* nondecreasing knot values in s */ long tknot_count, /* number of t knots */ INREAL tknot[], /* nondecreasing knot values in t */ long s_byte_stride, /* s step size in memory bytes */ long t_byte_stride, /* t step size in memory bytes */ INREAL ctlarray[], /* pointer to first control point */ long sorder, /* order of the spline in s parameter */ long torder, /* order of the spline in t parameter */ long type) /* description of range space */ { Mapdesc *mapdesc = maplist.locate( type ); if( mapdesc == 0 ) { do_nurbserror( 35 ); isDataValid = 0; return; } if( s_byte_stride < 0 ) { do_nurbserror( 34 ); isDataValid = 0; return; } if( t_byte_stride < 0 ) { do_nurbserror( 34 ); isDataValid = 0; return; } Knotvector sknotvector, tknotvector; sknotvector.init( sknot_count, s_byte_stride, sorder, sknot ); if( do_check_knots( &sknotvector, "surface" ) ) return; tknotvector.init( tknot_count, t_byte_stride, torder, tknot ); if( do_check_knots( &tknotvector, "surface" ) ) return; O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type); o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc); o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector, ctlarray, mapdesc->getNcoords() ); THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface ); }
static void delete_threadinfo(void) { struct threadinfo *threadinfo; threadinfo = getthreadinfo(); gwlist_destroy(threadinfo->joiners, NULL); if (threadinfo->wakefd_recv != -1) close(threadinfo->wakefd_recv); if (threadinfo->wakefd_send != -1) close(threadinfo->wakefd_send); if (threadinfo->number != -1) { THREAD(threadinfo->number) = NULL; active_threads--; } gw_assert(threadinfo != &mainthread); gw_free(threadinfo); }
/*----------------------------------------------------------------------------- * setnurbsproperty - * *----------------------------------------------------------------------------- */ void NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value ) { Mapdesc *mapdesc = maplist.locate( type ); if( mapdesc == 0 ) { do_nurbserror( 35 ); return; } if( ! mapdesc->isProperty( tag ) ) { do_nurbserror( 26 ); return; } Property *prop = new(propertyPool) Property( type, tag, value ); THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty ); }
void gwthread_join(long thread) { struct threadinfo *threadinfo; pthread_cond_t exit_cond; int ret; gw_assert(thread >= 0); lock(); threadinfo = THREAD(thread); if (threadinfo == NULL || threadinfo->number != thread) { /* The other thread has already exited */ unlock(); return; } /* Register our desire to be alerted when that thread exits, * and wait for it. */ ret = pthread_cond_init(&exit_cond, NULL); if (ret != 0) { warning(ret, "gwthread_join: cannot create condition variable."); unlock(); return; } if (!threadinfo->joiners) threadinfo->joiners = gwlist_create(); gwlist_append(threadinfo->joiners, &exit_cond); /* The wait immediately releases the lock, and reacquires it * when the condition is satisfied. So don't worry, we're not * blocking while keeping the table locked. */ pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, &threadtable_lock); ret = pthread_cond_wait(&exit_cond, &threadtable_lock); pthread_cleanup_pop(0); unlock(); if (ret != 0) warning(ret, "gwthread_join: error in pthread_cond_wait"); pthread_cond_destroy(&exit_cond); }
int gwthread_cancel(long thread) { struct threadinfo *threadinfo; int ret; gw_assert(thread >= 0); lock(); threadinfo = THREAD(thread); if (threadinfo == NULL || threadinfo->number != thread) { ret = -1; } else { ret = pthread_cancel(threadinfo->self); debug("gwlib.gwthread", 0, "Thread %ld (%s) canceled.", threadinfo->number, threadinfo->name); } unlock(); return ret; }
static void thread_reap(VALUE thr) { Thread *th; vector_t *v; th = THREAD(thr); v = th->obj_stk; vector_foreach(v, thread_reap_check); st_free_table(th->env_tbl); vector_free(th->obj_stk); vector_free(th->env_stk); vector_free(th->self_stk); vector_free(th->tok_stk); vector_free(th->stack); #ifdef SYMBOL_CACHE vector_free(th->modified_syms); #endif }