/* * ======== cmm_get_info ======== * Purpose: * Return the current memory utilization information. */ int cmm_get_info(struct cmm_object *hcmm_mgr, OUT struct cmm_info *cmm_info_obj) { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; u32 ul_seg; int status = 0; struct cmm_allocator *altr; struct cmm_mnode *mnode_obj = NULL; DBC_REQUIRE(cmm_info_obj != NULL); if (!hcmm_mgr) { status = -EFAULT; return status; } mutex_lock(&cmm_mgr_obj->cmm_lock); cmm_info_obj->ul_num_gppsm_segs = 0; /* # of SM segments */ /* Total # of outstanding alloc */ cmm_info_obj->ul_total_in_use_cnt = 0; /* min block size */ cmm_info_obj->ul_min_block_size = cmm_mgr_obj->ul_min_block_size; /* check SM memory segments */ for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) { /* get the allocator object for this segment id */ altr = get_allocator(cmm_mgr_obj, ul_seg); if (altr != NULL) { cmm_info_obj->ul_num_gppsm_segs++; cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_pa = altr->shm_base - altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = altr->ul_dsp_size + altr->ul_sm_size; cmm_info_obj->seg_info[ul_seg - 1].dw_gpp_base_pa = altr->shm_base; cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size = altr->ul_sm_size; cmm_info_obj->seg_info[ul_seg - 1].dw_dsp_base_va = altr->dw_dsp_base; cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size = altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va = altr->dw_vm_base - altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; mnode_obj = (struct cmm_mnode *) lst_first(altr->in_use_list_head); /* Count inUse blocks */ while (mnode_obj) { cmm_info_obj->ul_total_in_use_cnt++; cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt++; /* next node. */ mnode_obj = (struct cmm_mnode *) lst_next(altr->in_use_list_head, (struct list_head *)mnode_obj); } } } /* end for */ mutex_unlock(&cmm_mgr_obj->cmm_lock); return status; }
/* * ======== un_register_gppsm_seg ======== * Purpose: * UnRegister the SM allocator by freeing all its resources and * nulling cmm mgr table entry. * Note: * This routine is always called within cmm lock crit sect. */ static void un_register_gppsm_seg(struct cmm_allocator *psma) { struct cmm_mnode *mnode_obj = NULL; struct cmm_mnode *next_node = NULL; DBC_REQUIRE(psma != NULL); if (psma->free_list_head != NULL) { /* free nodes on free list */ mnode_obj = (struct cmm_mnode *)lst_first(psma->free_list_head); while (mnode_obj) { next_node = (struct cmm_mnode *)lst_next(psma->free_list_head, (struct list_head *) mnode_obj); lst_remove_elem(psma->free_list_head, (struct list_head *)mnode_obj); kfree((void *)mnode_obj); /* next node. */ mnode_obj = next_node; } kfree(psma->free_list_head); /* delete freelist */ /* free nodes on InUse list */ mnode_obj = (struct cmm_mnode *)lst_first(psma->in_use_list_head); while (mnode_obj) { next_node = (struct cmm_mnode *)lst_next(psma->in_use_list_head, (struct list_head *) mnode_obj); lst_remove_elem(psma->in_use_list_head, (struct list_head *)mnode_obj); kfree((void *)mnode_obj); /* next node. */ mnode_obj = next_node; } kfree(psma->in_use_list_head); /* delete InUse list */ } if ((void *)psma->dw_vm_base != NULL) MEM_UNMAP_LINEAR_ADDRESS((void *)psma->dw_vm_base); /* Free allocator itself */ kfree(psma); }
void main (void) { LIST *list; int done = 0; REC *rec; char line[80]; list = lst_init (); printf ("Type a list of names and ages. Empty line quits\n\n"); while (!done) { rec = lst_newnode (sizeof (REC)); gets (line); if ((done = (line[0] == '\0')) != 1) { strcpy (rec->name, line); gets (line); rec->age = atoi (line); lst_insertafter (list, rec, LST_HEAD (list)); } }; printf ("\nThe list you typed in was:\n\n"); for (rec = lst_first (list); rec; rec = lst_next (rec)) printf ("Name: %s, Age: %d\n", rec->name, rec->age); printf ("\nSorting the list...\n\n"); lst_mergesort (list, my_cmp); for (rec = lst_first (list); rec; rec = lst_next (rec)) printf ("Name: %s, Age: %d\n", rec->name, rec->age); lst_kill (list, lst_freenode); }
/* * ======== dev_notify_clients ======== * Purpose: * Notify all clients of this device of a change in device status. */ int dev_notify_clients(struct dev_object *hdev_obj, u32 ret) { int status = 0; struct dev_object *dev_obj = hdev_obj; void *proc_obj; for (proc_obj = (void *)lst_first(dev_obj->proc_list); proc_obj != NULL; proc_obj = (void *)lst_next(dev_obj->proc_list, (struct list_head *)proc_obj)) proc_notify_clients(proc_obj, (u32) ret); return status; }
/* * ======== rmm_free ======== */ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, bool reserved) { struct rmm_ovly_sect *sect; bool ret = true; DBC_REQUIRE(target); DBC_REQUIRE(reserved || segid < target->num_segs); DBC_REQUIRE(reserved || (dsp_addr >= target->seg_tab[segid].base && (dsp_addr + size) <= (target->seg_tab[segid]. base + target->seg_tab[segid]. length))); /* * Free or unreserve memory. */ if (!reserved) { ret = free_block(target, segid, dsp_addr, size); if (ret) target->seg_tab[segid].number--; } else { /* Unreserve memory */ sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list); while (sect != NULL) { if (dsp_addr == sect->addr) { DBC_ASSERT(size == sect->size); /* Remove from list */ lst_remove_elem(target->ovly_list, (struct list_head *)sect); kfree(sect); break; } sect = (struct rmm_ovly_sect *)lst_next(target->ovly_list, (struct list_head *)sect); } if (sect == NULL) ret = false; } return ret; }
/* * ======== cmm_free_buf ======== * Purpose: * Free the given buffer. */ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; int status = -EFAULT; struct cmm_mnode *mnode_obj = NULL; struct cmm_allocator *allocator = NULL; struct cmm_attrs *pattrs; DBC_REQUIRE(refs > 0); DBC_REQUIRE(buf_pa != NULL); if (ul_seg_id == 0) { pattrs = &cmm_dfltalctattrs; ul_seg_id = pattrs->ul_seg_id; } if (!hcmm_mgr || !(ul_seg_id > 0)) { status = -EFAULT; return status; } /* get the allocator for this segment id */ allocator = get_allocator(cmm_mgr_obj, ul_seg_id); if (allocator != NULL) { mutex_lock(&cmm_mgr_obj->cmm_lock); mnode_obj = (struct cmm_mnode *)lst_first(allocator->in_use_list_head); while (mnode_obj) { if ((u32) buf_pa == mnode_obj->dw_pa) { /* Found it */ lst_remove_elem(allocator->in_use_list_head, (struct list_head *)mnode_obj); /* back to freelist */ add_to_free_list(allocator, mnode_obj); status = 0; /* all right! */ break; } /* next node. */ mnode_obj = (struct cmm_mnode *) lst_next(allocator->in_use_list_head, (struct list_head *)mnode_obj); } mutex_unlock(&cmm_mgr_obj->cmm_lock); } return status; }
static void proc_apply(process_t *proc, term_t mod, term_t fun, term_t args) { celem_t *ip; int arity = lst_len(args); term_t mdi = intnum(proc->mod_index); term_t off = intnum(proc->ip - proc->code); ip = code_base_lookup(proc->base, mod, fun, arity, &proc->mod_index, &proc->code); if (ip == 0) { *(term_t *)apr_array_push(proc->cstack) = args; *(term_t *)apr_array_push(proc->cstack) = fun; *(term_t *)apr_array_push(proc->cstack) = mod; ip = code_base_lookup(proc->base, A_ERROR_HANDLER, A_UNDEFINED_FUNCTION, 3, &proc->mod_index, &proc->code); } else { // pushing args in reverse order: kludgy term_t l; int i; for (i = 0; i < arity; i++) *(term_t *)apr_array_push(proc->cstack) = AI_UNDEFINED; l = args; i = 0; while (l != nil) { (((term_t *)proc->cstack->elts)[proc->cstack->nelts-i-1]) = lst_value(l); l = lst_next(l); i++; } } *(term_t *)apr_array_push(proc->cstack) = mdi; *(term_t *)apr_array_push(proc->cstack) = off; proc->ip = ip; }
/* * ====== get_free_block ======== * Purpose: * Scan the free block list and return the first block that satisfies * the size. */ static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, u32 usize) { if (allocator) { struct cmm_mnode *mnode_obj = (struct cmm_mnode *) lst_first(allocator->free_list_head); while (mnode_obj) { if (usize <= (u32) mnode_obj->ul_size) { lst_remove_elem(allocator->free_list_head, (struct list_head *)mnode_obj); return mnode_obj; } /* next node. */ mnode_obj = (struct cmm_mnode *) lst_next(allocator->free_list_head, (struct list_head *)mnode_obj); } } return NULL; }
static apr_status_t port_buffer_send(buffer_t *buf, term_t io) { int avail; if (is_nil(io)) return 0; avail = buffer_available(buf); if (is_int(io)) { if (avail == 0) return APR_EINCOMPLETE; else buffer_put_byte(buf, int_value(io)); } else if (is_binary(io)) { int size = int_value2(bin_size(io)); if (size > avail) { buffer_put_data(buf, bin_data(io), avail); return APR_EINCOMPLETE; } else buffer_put_data(buf, bin_data(io), size); } if (is_list(io)) { while (is_cons(io)) { apr_status_t rs; rs = port_buffer_send(buf, lst_value(io)); if (rs != 0) return rs; io = lst_next(io); } } return APR_SUCCESS; }
static _linkage_block_ * _add_line_to_linkage_block_ (Line *line_to_add, Line *linkage_block_line, List *linkage_block_lst) { _linkage_block_ *linkage_block; assert (line_to_add); assert (linkage_block_line); assert (linkage_block_lst); assert (!lst_is_empty (linkage_block_lst)); assert (line_to_add -> scale < linkage_block_line -> scale); for (linkage_block = lst_first (linkage_block_lst); linkage_block && linkage_block -> line != linkage_block_line; linkage_block = lst_next (linkage_block_lst)); if (linkage_block && linkage_block -> line == linkage_block_line) { lst_add (line_to_add, linkage_block -> candidate_line_lst); linkage_block -> nb_of_candidates ++; } return linkage_block; }
/* * ======== dev_remove_proc_object ======== * Purpose: * Search for and remove a Proc object from the given list maintained * by the DEV * Parameters: * p_proc_object: Ptr to ProcObject to insert. * dev_obj Ptr to Dev Object where the list is. * Returns: * 0: If successful. * Requires: * List exists and is not empty * proc_obj != 0 * hdev_obj is a valid Dev handle. * Ensures: * Details: * List will be deleted when the DEV is destroyed. */ int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj) { int status = -EPERM; struct list_head *cur_elem; struct dev_object *dev_obj = (struct dev_object *)hdev_obj; DBC_REQUIRE(dev_obj); DBC_REQUIRE(proc_obj != 0); DBC_REQUIRE(dev_obj->proc_list != NULL); DBC_REQUIRE(!LST_IS_EMPTY(dev_obj->proc_list)); /* Search list for dev_obj: */ for (cur_elem = lst_first(dev_obj->proc_list); cur_elem != NULL; cur_elem = lst_next(dev_obj->proc_list, cur_elem)) { /* If found, remove it. */ if ((u32) cur_elem == proc_obj) { lst_remove_elem(dev_obj->proc_list, cur_elem); status = 0; break; } } return status; }
/** Get the shade determined by a given ray. * * @param ray the ray to trace. * @param t0 the start of the interval for which to get a shade. * @param t1 the end of the interval for which to get a shade. * @param depth the maximum number of times a reflect ray will be * cast for objects with non-NULL reflective color. * @param in_trans whether the ray is inside a transparent surface or not. * * * @return the color corresponding to the closest object hit by * <code>r</code> in the interval <code>[t0, t1]</code>. */ color_t ray_trace(ray3_t ray, float t0, float t1, int depth, bool in_trans) { assert(depth >= 0); color_t color = {0.0, 0.0, 0.0}; if (depth == 0) return color; hit_record_t hit_rec, closest_hit_rec; // Get a hit record for the closest object that is hit. bool hit_something = false; list356_itr_t* s = lst_iterator(surfaces); while (lst_has_next(s)) { surface_t* sfc = lst_next(s); if (sfc_hit(sfc, &ray, t0, t1, &hit_rec)) { if (hit_rec.t < t1) { hit_something = true; memcpy(&closest_hit_rec, &hit_rec, sizeof(hit_record_t)); t1 = hit_rec.t; } else assert("wrong"); } } lst_iterator_free(s); // If we hit something, color the pixel. if (hit_something) { surface_t* sfc = closest_hit_rec.sfc; // Specular reflection. if (spec_reflection) { if (sfc->refl_color != NULL) { color_t refl_color = get_specular_refl(&ray, &closest_hit_rec, depth, in_trans); add_scaled_color(&color, sfc->refl_color, &refl_color, 1.0f); } } // Tranparency if (transparency) { if (sfc->refr_index != -1) { color_t trans_color = get_transparency(&ray, &closest_hit_rec, depth, !in_trans); // Only add returned color, don't multiply by a surface_color. color.red += (trans_color.red); color.green += (trans_color.green); color.blue += (trans_color.blue); } } // Ambient shading. if (ambient_shading) { add_scaled_color(&color, sfc->ambient_color, &ambient_light, 1.0f); } // Lighting. if (lighting) { list356_itr_t* light_itr = lst_iterator(lights); while (lst_has_next(light_itr)) { light_t* light = lst_next(light_itr); vector3_t light_dir; pv_subtract(light->position, &(closest_hit_rec.hit_pt), &light_dir); normalize(&light_dir); // Check for global shadows. bool do_lighting = true; // Bool for if the shadow is caused by transparent surface. bool trans_shadow = false; ray3_t light_ray = {closest_hit_rec.hit_pt, light_dir}; float light_dist = dist(&closest_hit_rec.hit_pt, light->position); s = lst_iterator(surfaces); while (lst_has_next(s)) { surface_t* sfc = lst_next(s); if (sfc_hit(sfc, &light_ray, EPSILON, light_dist, &hit_rec)) { do_lighting = false; // If shadow is caused by transparent surface, we add // Lambertian shading only so our shadows are not opaque. if (hit_rec.sfc->refr_index != -1) trans_shadow = true; break; } } lst_iterator_free(s); if (!do_lighting) { continue; } // Lambertian shading. if (lambertian_shading) { if (!trans_shadow) { float scale = get_lambert_scale(&light_dir, &closest_hit_rec); add_scaled_color(&color, sfc->diffuse_color, light->color, scale); } } // Blin-Phong shading (if shadow is not caused by transparent // surface). if (blin_phong_shading) { if (!trans_shadow) { float phong_scale = get_blinn_phong_scale(&ray, &light_dir, &closest_hit_rec); add_scaled_color(&color, sfc->spec_color, light->color, phong_scale); } } } lst_iterator_free(light_itr); } } // if (hit_something) return color; }
/** Create a list of surfaces. */ list356_t* get_surfaces() { list356_t* surfaces = make_list() ; // Table. point3_t vertices[8] = { {0, 0, 1}, {8, 0, 1}, {0, 8, 1}, {8, 8, 1}, {0, 0, -1}, {8, 0, -1}, {0, 8, -1}, {8, 8, -1}, } ; int indices[] = { 0, 1, 3, 0, 3, 2, // top 0, 2, 6, 0, 6, 4, // left 4, 6, 7, 4, 7, 5, // bottom 1, 5, 7, 1, 7, 3, // right 2, 3, 7, 2, 7, 6, // back 0, 4, 5, 0, 5, 1 // front } ; int top_offset = 6 ; int offset = 36 ; list356_t* table_surfaces = make_list() ; for (int i=0; i<top_offset/3; ++i) { lst_add(table_surfaces, make_triangle( vertices[indices[3*i]], vertices[indices[3*i+1]], vertices[indices[3*i+2]], &RED, &RED, &WHITE, 10.0f)) ; } for (int i=top_offset/3; i<offset/3; ++i) { lst_add(table_surfaces, make_triangle( vertices[indices[3*i]], vertices[indices[3*i+1]], vertices[indices[3*i+2]], &GREEN, &GREEN, &WHITE, 10.0f)) ; } // Two purple spheres. lst_add(table_surfaces, make_sphere(6, 6, 1.75+.01, .75, &PURPLE, &PURPLE, &WHITE, 100.0f)) ; lst_add(table_surfaces, make_sphere(5, 2, 1.75+.01, .75, &PURPLE, &PURPLE, &WHITE, 100.0f)) ; // Transparent cube. point3_t cube_vertices[] = { {4, 0, 3}, {5, 0, 3}, {4, 1, 3}, {5, 1, 3}, {4, 0, 1.01}, {5, 0, 1.01}, {4, 1, 1.01}, {5, 1, 1.01}, } ; for (int i=0; i<offset/3; ++i) { surface_t* t = make_triangle( cube_vertices[indices[3*i]], cube_vertices[indices[3*i+1]], cube_vertices[indices[3*i+2]], &BLACK, &BLACK, &WHITE, 10.0f) ; t->refr_index = 1.1f ; t->atten = &GREENISH ; lst_add(surfaces, t) ; } list356_itr_t* itr = lst_iterator(table_surfaces) ; while (lst_has_next(itr)) lst_add(surfaces, lst_next(itr)) ; lst_free(table_surfaces) ; // Plane at z=-1. surface_t* plane = make_plane( (point3_t){0, 0, -1}, (point3_t){1, 0, -1}, (point3_t){1, 1, -1}, &LIGHT_GREY, &LIGHT_GREY, &BLACK, 10.0f) ; plane->refl_color = &LIGHT_GREY ; lst_add(surfaces, plane) ; return surfaces ; }
/* * retrieves a token converted from a pp-token; * ASSUMPTION: signed/unsigned integers are compatible on the host */ int (clx_next)(void) { lex_t *t; clx_ppos = clx_cpos; while (1) { t = lst_next(); clx_cpos = t->pos; switch(t->id) { case -1: strg_free((arena_t *)t->spell); break; case LEX_CREM: /* %= */ case LEX_CBAND: /* &= */ case LEX_CMUL: /* *= */ case LEX_CADD: /* += */ case LEX_CSUB: /* -= */ case LEX_CDIV: /* /= */ case LEX_CRSHFT: /* >>= */ case LEX_CLSHFT: /* <<= */ case LEX_CBXOR: /* ^= */ case LEX_CBOR: /* |= */ case '!': case '%': case '&': case LEX_INCR: /* ++ */ case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case LEX_DECR: /* -- */ case LEX_DEREF: /* -> */ case LEX_ANDAND: /* && */ case LEX_OROR: /* || */ case LEX_LEQ: /* <= */ case LEX_EQEQ: /* == */ case LEX_NEQ: /* != */ case LEX_GEQ: /* >= */ case LEX_RSHFT: /* >> */ case LEX_LSHFT: /* << */ case ':': case ';': case '<': case '=': case '>': case '?': case LEX_ELLIPSIS: /* ... */ case ']': case '[': case '^': case '{': case '|': case '}': case '~': case LEX_EOI: return t->id; case LEX_ID: return id(t); case LEX_CCON: { int w = 0; ux_t c = clx_ccon(t, &w); tval.type = (w)? ty_wchartype: ty_inttype; tval.u.c.v.u = c; clx_sym = &tval; } return t->id; case LEX_SCON: { int w = 0; sz_t len = scon(t, &w); tval.type = ty_array((!w)? ty_chartype: ty_wchartype, len, clx_cpos); tval.u.c.v.p = xcfp(strg_sbuf); clx_sym = &tval; } return t->id; case LEX_PPNUM: return ifcon(t); case LEX_SPACE: case LEX_NEWLINE: break; case LEX_SHARP: /* # */ case LEX_DSHARP: /* ## */ case LEX_UNKNOWN: { const char *p = LEX_SPELL(t); err_dpos(t->pos, (*p == '\\')? ERR_LEX_STRAYBS: ERR_LEX_UNKNOWN, p); } break; } } /* assert(!"impossible control flow -- should never reach here"); return t->id; */ }
/* * recognizes character constants; * ASSUMPTION: signed/unsigned integers are compatible on the host */ ux_t (clx_ccon)(lex_t *t, int *w) { int cbyte; sz_t len = 0; const char *ss, *s, *e; ux_t lim, c; #ifdef HAVE_ICONV iconv_t *cd; #endif /* HAVE_ICONV */ assert(t); assert(w); assert(BUFUNIT > 2); assert(ty_wuchartype); /* ensures types initialized */ assert(xgeu(xmxu, TG_UCHAR_MAX)); assert(xgeu(xmxu, TG_WUCHAR_MAX)); assert(ir_cur); ss = s = LEX_SPELL(t); if (*s == 'L') *w = 1, s++; e = ++s; /* skips ' */ if (*w) { cbyte = ty_wchartype->size; assert(cbyte <= BUFUNIT); lim = TG_WUCHAR_MAX; #ifdef HAVE_ICONV cd = main_ntow; #endif /* HAVE_ICONV */ } else { cbyte = 1; lim = TG_UCHAR_MAX; #ifdef HAVE_ICONV cd = main_ntoe; #endif /* HAVE_ICONV */ } switch(*e) { case '\'': /* empty; diagnosed elsewhere */ case '\0': /* unclosed; diagnosed elsewhere */ return xO; case '\\': /* escape sequences */ assert(sizeof(c) >= cbyte); c = lex_bs(t, ss, &e, lim, "character constant"); #if HAVE_ICONV if (cd && !(s[1] == 'x' || (s[1] >= '0' && s[1] <= '7'))) { char x = xnu(c); ICONV_DECL(&x, 1); assert(xe(xiu(x), c)); obuf = strg_sbuf, obufv = strg_sbuf; olen = strg_slen, olenv = strg_slen; ICONV_DO(cd, 1, {}); strg_sbuf = obuf, strg_slen = olen; /* for later reuse */ len = strg_slen - len - olenv; } else { #else /* !HAVE_ICONV */ { #endif /* HAVE_ICONV */ if (*w) memcpy(strg_sbuf, (char *)&c + ((LITTLE)? 0: sizeof(c)-cbyte), cbyte); else strg_sbuf[0] = xnu(c); len = cbyte; } break; default: /* ordinary chars */ #ifdef HAVE_ICONV if (cd) { do { e++; } while(!FIRSTUTF8(*e)); { ICONV_DECL((char *)s, e - s); obuf = strg_sbuf, obufv = strg_sbuf; olen = strg_slen, olenv = strg_slen; ICONV_DO(cd, 1, {}); strg_sbuf = obuf, strg_slen = olen; /* for later reuse */ len = strg_slen - len - olenv; } } else { #else /* !HAVE_ICONV */ { #endif /* HAVE_ICONV */ assert(TG_CHAR_BIT == CHAR_BIT); if (*w) { strg_sbuf[(LITTLE)? 0: cbyte-1] = *e; memset(strg_sbuf + ((LITTLE)? 1: 0), 0, cbyte-1); } else strg_sbuf[0] = *e; e++; len = cbyte; } break; } if (*e != '\'' && *e != '\0') { for (s = e; *e != '\0' && *e != '\''; e++) continue; err_dpos((FIRSTUTF8(*s))? lmap_spell(t, ss, s, e): t->pos, ERR_CONST_LARGECHAR); } else if (len != cbyte) { err_dpos(t->pos, (*w)? ERR_CONST_WIDENOTFIT: ERR_CONST_MBNOTFIT); return xO; } c = xO; memcpy(&c, strg_sbuf + ((LITTLE)? 0: sizeof(c)-cbyte), cbyte); if (*w) { switch(main_opt()->wchart) { case 0: /* long */ c = SYM_CROPSL(c); break; case 1: /* ushort */ c = SYM_CROPUS(c); break; case 2: /* int */ c = SYM_CROPSI(c); break; } } else /* int from char */ c = (main_opt()->uchar)? SYM_CROPUC(c): SYM_CROPSC(c); return c; } /* * recognizes string literals */ static sz_t scon(lex_t *t, int *w) { int cbyte; lex_t *n; sz_t clen = 0, len = 0; const char *ss, *s, *e; ux_t lim; #ifdef HAVE_ICONV iconv_t *cd; #endif assert(t); assert(w); assert(BUFUNIT > 2); assert(ty_wuchartype); /* ensures types initialized */ assert(xgeu(xmxu, TG_UCHAR_MAX)); assert(xgeu(xmxu, TG_WUCHAR_MAX)); assert(ir_cur); ss = s = LEX_SPELL(t); if (*s == 'L') *w = 1, s++; e = ++s; /* skips " */ while ((n = lst_peekns())->id == LEX_SCON) { if (*n->spell == 'L') { if (!*w) { /* mb + wide = wide */ err_dmpos(n->pos, ERR_CONST_MBWIDE, t->pos, NULL); err_dmpos(n->pos, ERR_CONST_MBWIDESTD, t->pos, NULL); *w = 2; /* silences warnings */ } } else if (*w == 1) { /* wide + mb = wide */ err_dmpos(n->pos, ERR_CONST_MBWIDE, t->pos, NULL); err_dmpos(n->pos, ERR_CONST_MBWIDESTD, t->pos, NULL); *w = 2; /* silences warnings */ } while ((t = lst_append(t, lst_next()))->id != LEX_SCON) continue; } clx_cpos = lmap_range(t->next->pos, t->pos); if (*w) { cbyte = ty_wchartype->size; assert(cbyte <= BUFUNIT); lim = TG_WUCHAR_MAX; #ifdef HAVE_ICONV cd = main_ntow; #endif /* HAVE_ICONV */ } else { cbyte = 1; lim = TG_UCHAR_MAX; #ifdef HAVE_ICONV cd = main_ntoe; #endif /* HAVE_ICONV */ } n = t->next; while (1) { while (1) { while (*e != '\\' && *e != '"' && *e != '\0') e++; if (e > s) { /* ordinary chars */ #ifdef HAVE_ICONV if (cd) { ICONV_DECL((char *)s, e - s); obuf = strg_sbuf, obufv = strg_sbuf + len; olen = strg_slen, olenv = strg_slen - len; ICONV_INIT(cd); ICONV_DO(cd, 0, {}); strg_sbuf = obuf, strg_slen = olen; /* for later reuse */ len += (strg_slen - len - olenv); } else { #else /* !HAVE_ICONV */ { #endif /* HAVE_ICONV */ sz_t d = e - s; assert(TG_CHAR_BIT == CHAR_BIT); while (len + (d*cbyte) > strg_slen) /* rarely iterates */ MEM_RESIZE(strg_sbuf, strg_slen += BUFUNIT); if (*w) { while (s < e) { strg_sbuf[len + ((ir_cur->f.little_endian)? 0: cbyte-1)] = *s++; memset(strg_sbuf + len + ((ir_cur->f.little_endian)? 1: 0), 0, cbyte-1); len += cbyte; } } else { memcpy(&strg_sbuf[len], s, d); len += d; } } for (; s < e; s++) if (FIRSTUTF8(*s)) clen++; } if (*e == '\\') { /* escape sequences */ ux_t c; assert(sizeof(c) >= cbyte); c = lex_bs(n, ss, &e, lim, "string literal"); #if HAVE_ICONV if (cd) { /* inserts initial seq before every esc seq */ ICONV_DECL(NULL, 0); UNUSED(ilenv); UNUSED(ibufv); obuf = strg_sbuf, obufv = strg_sbuf + len; olen = strg_slen, olenv = strg_slen - len; ICONV_INIT(cd); strg_sbuf = obuf, strg_slen = olen; /* for later reuse */ len += (strg_slen - len - olenv); } if (cd && !(s[1] == 'x' || (s[1] >= '0' && s[1] <= '7'))) { char x = xnu(c); ICONV_DECL(&x, 1); assert(xe(xiu(x), c)); obuf = strg_sbuf, obufv = strg_sbuf + len; olen = strg_slen, olenv = strg_slen - len; ICONV_DO(cd, 0, {}); strg_sbuf = obuf, strg_slen = olen; /* for later reuse */ len += (strg_slen - len - olenv); } else { #else /* !HAVE_ICONV */ { #endif /* HAVE_ICONV */ if (len + cbyte > strg_slen) MEM_RESIZE(strg_sbuf, strg_slen += BUFUNIT); if (*w) { if (LITTLE != ir_cur->f.little_endian) CHGENDIAN(c, sizeof(c)); memcpy(strg_sbuf+len, &c + ((ir_cur->f.little_endian)? 0: sizeof(c)-cbyte), cbyte); len += cbyte; } else strg_sbuf[len++] = xnu(c); } clen++; s = e; continue; } break; /* " or NUL */ } if (n == t) { if (len + cbyte > strg_slen) MEM_RESIZE(strg_sbuf, strg_slen += BUFUNIT); memset(strg_sbuf+len, 0, cbyte); len += cbyte; clen++; break; } while ((n = n->next)->id != LEX_SCON) if (n->id < 0) strg_free((arena_t *)n->spell); ss = s = LEX_SPELL(n); if (*s == 'L') s++; e = ++s; /* skips " */ } if (len % cbyte != 0) err_dpos(clx_cpos, ERR_CONST_WIDENOTFIT); if (*w) clen = (len /= cbyte); if (clen - 1 > TL_STR_STD) { /* -1 for NUL; note TL_STR_STD may warp around */ err_dpos(clx_cpos, ERR_CONST_LONGSTR); err_dpos(clx_cpos, ERR_CONST_LONGSTRSTD, (unsigned long)TL_STR_STD); } return len; } #define N 0 /* no suffix */ #define U 1 /* suffix: U */ #define L 2 /* suffix: L */ #define X 3 /* suffix: UL */ #ifdef SUPPORT_LL #define M 4 /* suffix: LL */ #define Z 5 /* suffix: ULL */ #endif /* SUPPORT_LL */ #define D 0 /* base: decimal */ #define H 1 /* base: octal or hexadecimal */ /* * determines the type of an integer constant */ static const char *icon(const char *cs, ux_t n, int ovf, int base, const lmap_t *pos) { static struct tab { ux_t limit; ty_t *type; #ifdef SUPPORT_LL } tab[Z+1][H+1][7]; #else /* !SUPPORT_LL */ } tab[X+1][H+1][5]; #endif /* SUPPORT_LL */ int suffix; struct tab *p; assert(cs); assert(pos); assert(ty_inttype); #ifdef SUPPORT_LL assert(xgeu(xmxu, TG_ULLONG_MAX)); #else /* !SUPPORT_LL */ assert(xgeu(xmxu, TG_ULONG_MAX)); #endif /* SUPPORT_LL */ if (xe(tab[N][D][0].limit, xO)) { /* no suffix, decimal; different in C90 */ tab[N][D][0].limit = TG_INT_MAX; tab[N][D][0].type = ty_inttype; tab[N][D][1].limit = TG_LONG_MAX; tab[N][D][1].type = ty_longtype; #ifdef SUPPORT_LL tab[N][D][2].limit = TG_LLONG_MAX; tab[N][D][2].type = ty_llongtype; tab[N][D][3].limit = TG_ULLONG_MAX; tab[N][D][3].type = ty_ullongtype; tab[N][D][4].limit = xmxu; tab[N][D][4].type = ty_inttype; #else /* SUPPORT_LL */ tab[N][D][2].limit = TG_ULONG_MAX; tab[N][D][2].type = ty_ulongtype; tab[N][D][3].limit = xmxu; tab[N][D][3].type = ty_inttype; #endif /* SUPPORT_LL */ /* no suffix, octal or hex */ tab[N][H][0].limit = TG_INT_MAX; tab[N][H][0].type = ty_inttype; tab[N][H][1].limit = TG_UINT_MAX; tab[N][H][1].type = ty_unsignedtype; tab[N][H][2].limit = TG_LONG_MAX; tab[N][H][2].type = ty_longtype; tab[N][H][3].limit = TG_ULONG_MAX; tab[N][H][3].type = ty_ulongtype; #ifdef SUPPORT_LL tab[N][H][4].limit = TG_LLONG_MAX; tab[N][H][4].type = ty_llongtype; tab[N][H][5].limit = TG_ULLONG_MAX; tab[N][H][5].type = ty_ullongtype; tab[N][H][6].limit = xmxu; tab[N][H][6].type = ty_inttype; #else /* !SUPPORT_LL */ tab[N][H][4].limit = xmxu; tab[N][H][4].type = ty_inttype; #endif /* SUPPORT_LL */ /* U, decimal, octal or hex */ tab[U][H][0].limit = tab[U][D][0].limit = TG_UINT_MAX; tab[U][H][0].type = tab[U][D][0].type = ty_unsignedtype; tab[U][H][1].limit = tab[U][D][1].limit = TG_ULONG_MAX; tab[U][H][1].type = tab[U][D][1].type = ty_ulongtype; #ifdef SUPPORT_LL tab[U][H][2].limit = tab[U][D][2].limit = TG_ULLONG_MAX; tab[U][H][2].type = tab[U][D][2].type = ty_ullongtype; tab[U][H][3].limit = tab[U][D][3].limit = xmxu; tab[U][H][3].type = tab[U][D][3].type = ty_inttype; #else /* !SUPPORT_LL */ tab[U][H][2].limit = tab[U][D][2].limit = xmxu; tab[U][H][2].type = tab[U][D][2].type = ty_inttype; #endif /* SUPPORT_LL */ /* L, decimal; different in C90 */ tab[L][D][0].limit = TG_LONG_MAX; tab[L][D][0].type = ty_longtype; #ifdef SUPPORT_LL tab[L][D][1].limit = TG_LLONG_MAX; tab[L][D][1].type = ty_llongtype; tab[L][D][2].limit = TG_ULLONG_MAX; tab[L][D][2].type = ty_ullongtype; tab[L][D][3].limit = xmxu; tab[L][D][3].type = ty_inttype; #else /* !SUPPORT_LL */ tab[L][D][1].limit = TG_ULONG_MAX; tab[L][D][1].type = ty_ulongtype; tab[L][D][2].limit = xmxu; tab[L][D][2].type = ty_inttype; #endif /* SUPPORT_LL */ /* L, octal or hex */ tab[L][H][0].limit = TG_LONG_MAX; tab[L][H][0].type = ty_longtype; tab[L][H][1].limit = TG_ULONG_MAX; tab[L][H][1].type = ty_ulongtype; #ifdef SUPPORT_LL tab[L][H][2].limit = TG_LLONG_MAX; tab[L][H][2].type = ty_llongtype; tab[L][H][3].limit = TG_ULLONG_MAX; tab[L][H][3].type = ty_ullongtype; tab[L][H][4].limit = xmxu; tab[L][H][4].type = ty_inttype; #else /* !SUPPORT_LL */ tab[L][H][2].limit = xmxu; tab[L][H][2].type = ty_inttype; #endif /* SUPPORT_LL */ /* UL, decimal, octal or hex */ tab[X][H][0].limit = tab[X][D][0].limit = TG_ULONG_MAX; tab[X][H][0].type = tab[X][D][0].type = ty_ulongtype; #ifdef SUPPORT_LL tab[X][H][1].limit = tab[X][D][1].limit = TG_ULLONG_MAX; tab[X][H][1].type = tab[X][D][1].type = ty_ullongtype; tab[X][H][2].limit = tab[X][D][2].limit = xmxu; tab[X][H][2].type = tab[X][D][2].type = ty_inttype; #else /* !SUPPORT_LL */ tab[X][H][1].limit = tab[X][D][1].limit = xmxu; tab[X][H][1].type = tab[X][D][1].type = ty_inttype; #endif /* SUPPORT_LL */ #ifdef SUPPORT_LL /* LL, decimal, octal or hex */ tab[M][H][0].limit = tab[M][D][0].limit = TG_LLONG_MAX; tab[M][H][0].type = tab[M][D][0].type = ty_llongtype; tab[M][H][1].limit = tab[M][D][1].limit = TG_ULLONG_MAX; tab[M][H][1].type = tab[M][D][1].type = ty_ullongtype; tab[M][H][2].limit = tab[M][D][2].limit = xmxu; tab[M][H][2].type = tab[M][D][2].type = ty_inttype; /* ULL, decimal, octal or hex */ tab[Z][H][0].limit = tab[Z][D][0].limit = TG_ULLONG_MAX; tab[Z][H][0].type = tab[Z][D][0].type = ty_ullongtype; tab[Z][H][1].limit = tab[Z][D][1].limit = xmxu; tab[Z][H][1].type = tab[Z][D][1].type = ty_inttype; #endif /* SUPPORT_LL */ } base = (base == 10)? D: H; suffix = N; if (tolower((unsigned char)cs[0]) == 'l') { #ifdef SUPPORT_LL if (cs[1] == cs[0]) cs += 2, suffix = M; else #endif /* SUPPORT_LL */ cs++, suffix = L; } if (tolower((unsigned char)cs[0]) == 'u') cs++, suffix++; if (suffix <= U && tolower((unsigned char)cs[0]) == 'l') { #ifdef SUPPORT_LL if (cs[1] == cs[0]) cs += 2, suffix += M; else #endif /* SUPPORT_LL */ cs++, suffix += L; } for (p = tab[suffix][base]; xgu(n, p->limit); p++) continue; if (ovf || (xe(p->limit, xmxu) && p->type == ty_inttype)) { err_dpos(pos, ERR_CONST_LARGEINT); #ifdef SUPPORT_LL n = TG_ULLONG_MAX; tval.type = ty_ullongtype; #else /* !SUPPORT_LL */ n = TG_ULONG_MAX; tval.type = ty_ulongtype; #endif /* SUPPORT_LL */ } else tval.type = p->type; #ifdef SUPPORT_LL if (suffix % 2 == 0 && base == D && TY_ISUNSIGN(p->type)) err_dpos(pos, ERR_CONST_LARGEUNSIGN); else if (tval.type == ty_llongtype && (suffix == N || suffix == L) && xleu(n, TG_ULONG_MAX)) { err_dpos(pos, ERR_CONST_UNSIGNINC90); if (main_opt()->std == 1) tval.type = ty_ulongtype; } if ((TY_ISLLONG(tval.type) || TY_ISULLONG(tval.type))) err_dpos(pos, ERR_CONST_LLONGINC90, tval.type); #endif /* SUPPORT_LL */ #ifdef SUPPORT_LL if (tval.type->op == TY_INT || tval.type->op == TY_LONG || tval.type->op == TY_LLONG) #else /* !SUPPORT_LL */ if (tval.type->op == TY_INT || tval.type->op == TY_LONG) #endif /* SUPPORT_LL */ tval.u.c.v.s = n; else tval.u.c.v.u = n; return cs; } #undef H #undef D #undef Z #undef M #undef X #undef L #undef U #undef N /* * determines the type of a floating constant; * ASSUMPTION: fp types of the host are same as those of the target */ static const char *fcon(const char *cs, long double ld, const lmap_t *pos) { assert(cs); assert(pos); assert(ty_floattype); /* ensures types initiailized */ switch(*cs) { case 'f': case 'F': cs++; /* skips f or F */ if ((OVF(ld) && errno == ERANGE) || ld > TG_FLT_MAX) { err_dpos(pos, ERR_CONST_LARGEFP); ld = TG_FLT_MAX; } else if ((ld == 0.0 && errno == ERANGE) || (ld > 0.0 && ld < TG_FLT_MIN)) { err_dpos(pos, ERR_CONST_TRUNCFP); ld = 0.0f; } tval.type = ty_floattype; tval.u.c.v.f = (float)ld; break; case 'l': case 'L': cs++; /* skips l or L */ if ((OVF(ld) && errno == ERANGE) || ld > TG_LDBL_MAX) { err_dpos(pos, ERR_CONST_LARGEFP); ld = TG_LDBL_MAX; } else if ((ld == 0.0 && errno == ERANGE) || (ld > 0.0 && ld < TG_LDBL_MIN)) err_dpos(pos, ERR_CONST_TRUNCFP); tval.type = ty_ldoubletype; tval.u.c.v.ld = (long double)ld; break; default: if ((OVF(ld) && errno == ERANGE) || ld > TG_DBL_MAX) { err_dpos(pos, ERR_CONST_LARGEFP); ld = (double)TG_DBL_MAX; } else if ((ld == 0.0 && errno == ERANGE) || (ld > 0.0 && ld < TG_DBL_MIN)) { err_dpos(pos, ERR_CONST_TRUNCFP); ld = 0.0; } tval.type = ty_doubletype; tval.u.c.v.d = (double)ld; break; } return cs; } /* * recognizes integer or floating constants; * ASSUMPTION: strtold() supported on the host */ static int ifcon(lex_t *t) { ux_t n; int b, d; long double ld; int err = 0, ovf = 0; const char *ss, *s; char *p = "0123456789abcdef"; /* no const for reuse with strtold() */ assert(t); ss = s = LEX_SPELL(t); if (*s == '.') goto fcon; n = xO; if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && isxdigit(((unsigned char *)s)[2])) { /* 0x[0-9] */ b = 16; s++; /* skips 0 */ while (isxdigit(*(unsigned char *)++s)) { d = strchr(p, tolower(*(unsigned char *)s)) - p; if (xt(xba(n, xbc(xsrl(xmxu, 4))))) ovf = 1; n = xau(xsl(n, 4), xiu(d)); } s = icon(s, n, ovf, b, t->pos); b = LEX_ICON; } else { /* 0 or other digits */ b = (*s == '0')? 8: 10; if (b == 8) while (isdigit(*(unsigned char *)s)) { d = *s++ - '0'; if (*s == '8' || *s == '9') p = (char *)s, err = 1; if (xt(xba(n, xbc(xsrl(xmxu, 3))))) ovf = 1; n = xau(xsl(n, 3), xiu(d)); } else /* b == 10 */ while (isdigit(*(unsigned char *)s)) { d = *s++ - '0'; if (xgu(n, xdu(xsu(xmxu, xiu(d)), xiu(10)))) ovf = 1; n = xau(xmu(xiu(10), n), xiu(d)); } fcon: if (b != 16 && (*s == '.' || *s == 'e' || *s == 'E')) { if (*s == '.') do { s++; /* skips . and digits */ } while(isdigit(*s)); if (*s == 'e' || *s == 'E') { if (*++s == '-' || *s == '+') /* skips e or E */ s++; /* skips - or + */ if (!isdigit(*s)) { err_dpos(lmap_spell(t, ss, s, s+1), ERR_CONST_NOEXPDIG); err = 1; } } if (!err) { errno = 0; ld = strtold(ss, &p); s = fcon((s = p), ld, t->pos); } b = LEX_FCON; } else { if (err) err_dpos(lmap_spell(t, ss, p, p+1), ERR_CONST_ILLOCTESC); else s = icon(s, n, ovf, b, t->pos); b = LEX_ICON; } } if (*s && !err) { for (p = (char *)s; *p; p++) continue; err_dpos(lmap_spell(t, ss, s, p), ERR_CONST_PPNUMSFX, s, b); err = 1; } clx_sym = (err)? NULL: &tval; return b; }
/** * Get the color from reflection and refraction for transparent objects. * * @param ray the viewing ray * @param hit_rec the hit record for the point being colored. * @param depth the current ray-tracing recursion depth. * @param in_trans whether the ray is inside a transparent surface or not. * * @return the color to add from transparency of ray. */ color_t get_transparency(ray3_t* ray, hit_record_t* hit_rec, int depth, bool in_trans) { //debug("get_transparency"); // Use notation from Shirley and Marschner: // d - ray // n - normal = closest_hit_rec->normal // <i>n></i> - refractive index // t - transformed ray direction // Calculate reflected ray refl_ray: r = reflect(d,n). vector3_t normal = hit_rec->normal; vector3_t refl_vector; reflect(ray, &normal, &refl_vector); normalize(&refl_vector); ray3_t refl_ray = { hit_rec->hit_pt, refl_vector }; // Store locally for cleaner code. surface_t* sfc = hit_rec->sfc; float index = sfc->refr_index; // Variables populated in if/else blocks: color_t trans_color; color_t k; float c; vector3_t t_vec; // Normalize ray_dir for dot product vector3_t ray_dir = ray->dir; normalize(&ray_dir); if (dot(&ray_dir, &normal) < 0) { // Calculate direction refracted (transformed) ray, t_vec; refract(ray, &normal, index, &t_vec, in_trans); c = ( -1.0f * dot(&ray_dir, &normal)); k = (color_t) {1.0f, 1.0f, 1.0f}; } else { // Intensity of light diminishes by the attenuation constant of the // surface proportionally to the distance the ray of light travels // through the surface. To calculate this distance that the ray of // light spends in the surface we follow a procedure similar to the // procedure of shadows. We Iterate through all surfaces looking for // the closest hit object in the direction of the refracted ray. Then // we take the distance between the first hit records hit_pt and the // closest hit record's hit_pt which is on the closest object. vector3_t dist_vec; refract(ray, &normal, index, &dist_vec, in_trans); ray3_t t_ray = {hit_rec->hit_pt, dist_vec}; hit_record_t t_hit_rec, t_closest_hit_rec; // Get a hit record for the closest object that is hit in dir t_ray. bool hit_something = false; float t1 = FLT_MAX; list356_itr_t* s = lst_iterator(surfaces); while (lst_has_next(s)) { surface_t* sfc = lst_next(s); if (sfc_hit(sfc, &t_ray, EPSILON, t1, &t_hit_rec)) { if (t_hit_rec.t < t1) { hit_something = true; memcpy(&t_closest_hit_rec, &t_hit_rec, sizeof(hit_record_t)); t1 = t_hit_rec.t; } } } lst_iterator_free(s); float t = dist(&hit_rec->hit_pt, &t_closest_hit_rec.hit_pt); // Calculate attenuation. color_t* a = sfc->atten; k = (color_t) { exp(-1.0f * (a->red) * t), exp(-1.0f * (a->green) * t), exp(-1.0f * (a->blue) * t) }; vector3_t neg_normal; // neg_normal = -n multiply(&normal, -1.0f, &neg_normal); // inv_index = 1/n = 1/refr_index float inv_index = 1.0f/index; if (refract(ray, &neg_normal, inv_index, &t_vec, in_trans)) { c = dot(&t_vec, &normal); } else { trans_color = ray_trace(refl_ray, EPSILON, FLT_MAX, depth-1, !in_trans); trans_color.red = trans_color.red*k.red; trans_color.green = trans_color.green*k.green; trans_color.blue = trans_color.blue*k.blue; //return (color_t) {1.0f, 1.0f, 0.0f}; return trans_color; } } float R0 = (( (index - 1)*(index - 1) )/( (index + 1)*(index + 1) )); float R = (R0 + (1 - R0)*((1 - c)*(1 - c)*(1 - c)*(1 - c)*(1 - c))); color_t trans_color1, trans_color2; // Recursively ray trace on the reflected ray and the refracted ray. trans_color1 = ray_trace(refl_ray, EPSILON, FLT_MAX, depth-1, !in_trans); ray3_t t_ray = {hit_rec->hit_pt, t_vec}; trans_color2 = ray_trace(t_ray, EPSILON, FLT_MAX, depth-1, !in_trans); // Combine the reflected and refracted ray and return. trans_color.red = k.red*( (R*trans_color1.red) + ((1.0f - R)*trans_color2.red)); trans_color.green = k.green*( (R*trans_color1.green) + ((1.0f - R)*trans_color2.green)); trans_color.blue = k.blue*( (R*trans_color1.blue) + ((1.0f - R)*trans_color2.blue)); return trans_color; }
/* * ======== add_to_free_list ======== * Purpose: * Coelesce node into the freelist in ascending size order. */ static void add_to_free_list(struct cmm_allocator *allocator, struct cmm_mnode *pnode) { struct cmm_mnode *node_prev = NULL; struct cmm_mnode *node_next = NULL; struct cmm_mnode *mnode_obj; u32 dw_this_pa; u32 dw_next_pa; DBC_REQUIRE(pnode != NULL); DBC_REQUIRE(allocator != NULL); dw_this_pa = pnode->dw_pa; dw_next_pa = NEXT_PA(pnode); mnode_obj = (struct cmm_mnode *)lst_first(allocator->free_list_head); while (mnode_obj) { if (dw_this_pa == NEXT_PA(mnode_obj)) { /* found the block ahead of this one */ node_prev = mnode_obj; } else if (dw_next_pa == mnode_obj->dw_pa) { node_next = mnode_obj; } if ((node_prev == NULL) || (node_next == NULL)) { /* next node. */ mnode_obj = (struct cmm_mnode *) lst_next(allocator->free_list_head, (struct list_head *)mnode_obj); } else { /* got 'em */ break; } } /* while */ if (node_prev != NULL) { /* combine with previous block */ lst_remove_elem(allocator->free_list_head, (struct list_head *)node_prev); /* grow node to hold both */ pnode->ul_size += node_prev->ul_size; pnode->dw_pa = node_prev->dw_pa; pnode->dw_va = node_prev->dw_va; /* place node on mgr nodeFreeList */ delete_node((struct cmm_object *)allocator->hcmm_mgr, node_prev); } if (node_next != NULL) { /* combine with next block */ lst_remove_elem(allocator->free_list_head, (struct list_head *)node_next); /* grow da node */ pnode->ul_size += node_next->ul_size; /* place node on mgr nodeFreeList */ delete_node((struct cmm_object *)allocator->hcmm_mgr, node_next); } /* Now, let's add to freelist in increasing size order */ mnode_obj = (struct cmm_mnode *)lst_first(allocator->free_list_head); while (mnode_obj) { if (pnode->ul_size <= mnode_obj->ul_size) break; /* next node. */ mnode_obj = (struct cmm_mnode *)lst_next(allocator->free_list_head, (struct list_head *)mnode_obj); } /* if mnode_obj is NULL then add our pnode to the end of the freelist */ if (mnode_obj == NULL) { lst_put_tail(allocator->free_list_head, (struct list_head *)pnode); } else { /* insert our node before the current traversed node */ lst_insert_before(allocator->free_list_head, (struct list_head *)pnode, (struct list_head *)mnode_obj); } }
/* * ======== rmm_alloc ======== */ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, u32 align, u32 *dsp_address, bool reserve) { struct rmm_ovly_sect *sect; struct rmm_ovly_sect *prev_sect = NULL; struct rmm_ovly_sect *new_sect; u32 addr; int status = 0; DBC_REQUIRE(target); DBC_REQUIRE(dsp_address != NULL); DBC_REQUIRE(size > 0); DBC_REQUIRE(reserve || (target->num_segs > 0)); DBC_REQUIRE(refs > 0); if (!reserve) { if (!alloc_block(target, segid, size, align, dsp_address)) { status = -ENOMEM; } else { /* Increment the number of allocated blocks in this * segment */ target->seg_tab[segid].number++; } goto func_end; } /* An overlay section - See if block is already in use. If not, * insert into the list in ascending address size. */ addr = *dsp_address; sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list); /* Find place to insert new list element. List is sorted from * smallest to largest address. */ while (sect != NULL) { if (addr <= sect->addr) { /* Check for overlap with sect */ if ((addr + size > sect->addr) || (prev_sect && (prev_sect->addr + prev_sect->size > addr))) { status = -ENXIO; } break; } prev_sect = sect; sect = (struct rmm_ovly_sect *)lst_next(target->ovly_list, (struct list_head *) sect); } if (!status) { /* No overlap - allocate list element for new section. */ new_sect = kzalloc(sizeof(struct rmm_ovly_sect), GFP_KERNEL); if (new_sect == NULL) { status = -ENOMEM; } else { lst_init_elem((struct list_head *)new_sect); new_sect->addr = addr; new_sect->size = size; new_sect->page = segid; if (sect == NULL) { /* Put new section at the end of the list */ lst_put_tail(target->ovly_list, (struct list_head *)new_sect); } else { /* Put new section just before sect */ lst_insert_before(target->ovly_list, (struct list_head *)new_sect, (struct list_head *)sect); } } } func_end: return status; }
/** Get the shade determined by a given ray. * * @param ray the ray to trace. * @param t0 the start of the interval for which to get a shade. * @param t1 the end of the interval for which to get a shade. * @param depth the maximum number of times a reflect ray will be * cast for objects with non-NULL reflective color. * * @return the color corresponding to the closest object hit by * <code>r</code> in the interval <code>[t0, t1]</code>. */ color_t ray_trace(ray3_t ray, float t0, float t1, int depth) { assert(depth >= 0) ; color_t color = {0.0, 0.0, 0.0} ; if (depth ==0) return color ; hit_record_t hit_rec, closest_hit_rec ; // Get a hit record for the closest object that is hit. bool hit_something = false ; list356_itr_t* s = lst_iterator(surfaces) ; while (lst_has_next(s)) { surface_t* sfc = lst_next(s) ; if (sfc_hit(sfc, &ray, t0, t1, &hit_rec)) { if (hit_rec.t < t1) { hit_something = true ; memcpy(&closest_hit_rec, &hit_rec, sizeof(hit_record_t)) ; t1 = hit_rec.t ; } } } lst_iterator_free(s) ; // If we hit something, color the pixel. if (hit_something) { surface_t* sfc = closest_hit_rec.sfc ; // Specular reflection. if (sfc->refl_color != NULL) { color_t refl_color = get_specular_refl(&ray, &closest_hit_rec, depth) ; add_scaled_color(&color, sfc->refl_color, &refl_color, 1.0f) ; } // Ambient shading. add_scaled_color(&color, sfc->ambient_color, &ambient_light, 1.0f) ; // Lighting. list356_itr_t* light_itr = lst_iterator(lights) ; while (lst_has_next(light_itr)) { light_t* light = lst_next(light_itr) ; vector3_t light_dir ; pv_subtract(light->position, &(closest_hit_rec.hit_pt), &light_dir) ; normalize(&light_dir) ; // Check for global shadows. bool do_lighting = true ; ray3_t light_ray = {closest_hit_rec.hit_pt, light_dir} ; float light_dist = dist(&closest_hit_rec.hit_pt, light->position) ; s = lst_iterator(surfaces) ; while (lst_has_next(s)) { surface_t* sfc = lst_next(s) ; if (sfc_hit(sfc, &light_ray, EPSILON, light_dist, &hit_rec)) { do_lighting = false ; break ; } } lst_iterator_free(s) ; if (!do_lighting) { continue ; } // Lambertian shading. float scale = get_lambert_scale(&light_dir, &closest_hit_rec) ; add_scaled_color(&color, sfc->diffuse_color, light->color, scale) ; // Blin-Phong shading. float phong_scale = get_blinn_phong_scale(&ray, &light_dir, &closest_hit_rec) ; add_scaled_color(&color, sfc->spec_color, light->color, phong_scale) ; } // while(lst_has_next(light_itr)) lst_iterator_free(light_itr) ; } // if (hit_something) return color ; }