void *_tc_recdecode(const void *ptr, int size, int *sp, void *op){ char *res = MYMALLOC(size + 1); if(!res) return NULL; memcpy(res, ptr, size); *sp = size; return res; }
void *_tc_recdecode(const void *ptr, int size, int *sp, void *op){ if(!_tc_lzo_init){ if(lzo_init() != LZO_E_OK) return NULL; _tc_lzo_init = false; } lzo_bytep buf; lzo_uint bsiz; int rat = 6; while(true){ bsiz = (size + 256) * rat + 3; buf = MYMALLOC(bsiz + 1); if(!buf) return NULL; int rv = lzo1x_decompress_safe((lzo_bytep)ptr, size, buf, &bsiz, NULL); if(rv == LZO_E_OK){ break; } else if(rv == LZO_E_OUTPUT_OVERRUN){ MYFREE(buf); rat *= 2; } else { MYFREE(buf); return NULL; } } buf[bsiz] = '\0'; if(sp) *sp = bsiz; return (char *)buf; }
void DMUMPS_alloc(DMUMPS_STRUC_C **dmumps_par){ MYMALLOC((*dmumps_par),1,DMUMPS_STRUC_C); (*dmumps_par)->irn = NULL; (*dmumps_par)->jcn = NULL; (*dmumps_par)->a = NULL; (*dmumps_par)->irn_loc = NULL; (*dmumps_par)->jcn_loc = NULL; (*dmumps_par)->a_loc = NULL; (*dmumps_par)->eltptr = NULL; (*dmumps_par)->eltvar = NULL; (*dmumps_par)->a_elt = NULL; (*dmumps_par)->perm_in = NULL; (*dmumps_par)->colsca = NULL; (*dmumps_par)->rowsca = NULL; (*dmumps_par)->rhs = NULL; (*dmumps_par)->redrhs = NULL; (*dmumps_par)->rhs_sparse = NULL; (*dmumps_par)->irhs_sparse = NULL; (*dmumps_par)->irhs_ptr = NULL; (*dmumps_par)->pivnul_list = NULL; (*dmumps_par)->listvar_schur = NULL; (*dmumps_par)->schur = NULL; (*dmumps_par)->sym_perm = NULL; (*dmumps_par)->uns_perm = NULL; }
static VALUE swinfont_new(int argc,VALUE * argv, VALUE klass){ /* argv: fontname,height [,style,weight,width,escape,orient,pitchfamily] */ /* pitch: 0 as default,1 as fixed, 2 as variable, 0x4 for truetype family: 0x0 as dontcare,0x10 as roman, 0x20 as swiss,0x30 as modern,0x40 as script 0x50 as decorative weight: 0-9 */ struct SwinFont* sf; VALUE robj; int height,width,escape,orient,weight; DWORD italic,underline,strike; /*,charset,oprec,cprec,quality; */ DWORD pitchfamily; unsigned char charset; VALUE faceobj; TCHAR* face; int facelen; if(argc<2){ rb_raise(rb_eArgError,"Need font face name and height"); return Qfalse; } robj = Data_Make_Struct(cSwinFont, struct SwinFont, 0, release_font, sf); faceobj = SWIN_API_STR(argv[0]); facelen = RSTRING_LEN(faceobj); /* face = sf->fontname = malloc(facelen+1);*/ MYMALLOC(sf->fontname,facelen+1,Qfalse); face = sf->fontname; lstrcpyn(face, (TCHAR*)RSTRING_PTR(faceobj),facelen/sizeof(TCHAR)+1); sf->height = height = NUM2INT(argv[1]); sf->style = (argc>2 && argv[2]!=Qnil)? NUM2UINT(argv[2]) : 0; italic = (sf->style) & SWINFONT_ITALIC; underline = (sf->style) & SWINFONT_ULINE; strike = (sf->style) & SWINFONT_STRIKE; sf->weight = weight = ((argc>3 && argv[3]!=Qnil)? NUM2INT(argv[3]) : 0)*100; sf->width = width = (argc>4 && argv[4]!=Qnil)? NUM2INT(argv[4]) : 0; sf->escape = escape = (argc>5 && argv[5]!=Qnil)? NUM2INT(argv[5]) : 0; sf->orient = orient = (argc>6 && argv[6]!=Qnil)? NUM2INT(argv[6]) : 0; sf->pitchfamily = pitchfamily = (argc>7 && argv[7]!=Qnil)? NUM2INT(argv[7]) : 0x04; sf->charset = charset = (argc>8 && argv[8]!=Qnil)? NUM2INT(argv[8]) : DEFAULT_CHARSET; sf->hfont = CreateFont(height,width,escape,orient,weight, italic,underline,strike,charset, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, pitchfamily,face); if(!sf->hfont){ rb_raise(rb_eRuntimeError,"failed to create font"); return Qfalse; } return robj; }
/*************************************************************************** * * block-cache related functions * *************************************************************************** */ int bc_init(void) { if (unlikely(blk_cache_init)) return 1; if (unlikely(!enable_blk_cache)) return 0; if (!(blk_cache = (block_cache_t*)MYMALLOC(sizeof(block_cache_t)))) return 0; blk_cache->blks = rbt_create(); if (!blk_cache->blks) { free(blk_cache); return 0; } lru_init(); blk_cache_init = 1; return 1; }
void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int i,j,pos; int *ptr_int; double *ptr_matlab; #if MUMPS_ARITH == MUMPS_ARITH_z double *ptri_matlab; #endif mwSize tmp_m,tmp_n; /* C pointer for input parameters */ size_t inst_address; mwSize n,m,ne, netrue ; int job; mwIndex *irn_in,*jcn_in; /* variable for multiple and sparse rhs */ int posrhs; mwSize nbrhs,ldrhs, nz_rhs; mwIndex *irhs_ptr, *irhs_sparse; double *rhs_sparse; #if MUMPS_ARITH == MUMPS_ARITH_z double *im_rhs_sparse; #endif DMUMPS_STRUC_C *dmumps_par; int dosolve = 0; int donullspace = 0; int doanalysis = 0; int dofactorize = 0; EXTRACT_FROM_MATLAB_TOVAL(JOB,job); doanalysis = (job == 1 || job == 4 || job == 6); dofactorize = (job == 2 || job == 4 || job == 5 || job == 6); dosolve = (job == 3 || job == 5 || job == 6); if(job == -1){ DMUMPS_alloc(&dmumps_par); EXTRACT_FROM_MATLAB_TOVAL(SYM,dmumps_par->sym); dmumps_par->job = -1; dmumps_par->par = 1; dmumps_c(dmumps_par); dmumps_par->nz = -1; dmumps_par->nz_alloc = -1; }else{ EXTRACT_FROM_MATLAB_TOVAL(INST,inst_address); ptr_int = (int *) inst_address; dmumps_par = (DMUMPS_STRUC_C *) ptr_int; if(job == -2){ dmumps_par->job = -2; dmumps_c(dmumps_par); /* If colsca/rowsca were freed by MUMPS, dmumps_par->colsca/rowsca are now null. Application of MYFREE in call below thus ok */ DMUMPS_free(&dmumps_par); }else{ /* check of input arguments */ n = mxGetN(A_IN); m = mxGetM(A_IN); if (!mxIsSparse(A_IN) || n != m ) mexErrMsgTxt("Input matrix must be a sparse square matrix"); jcn_in = mxGetJc(A_IN); ne = jcn_in[n]; irn_in = mxGetIr(A_IN); dmumps_par->n = (int)n; if(dmumps_par->n != n) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); if(dmumps_par->sym != 0) netrue = (n+ne)/2; else netrue = ne; if(dmumps_par->nz_alloc < netrue || dmumps_par->nz_alloc >= 2*netrue){ MYFREE(dmumps_par->jcn); MYFREE(dmumps_par->irn); MYFREE(dmumps_par->a); MYMALLOC((dmumps_par->jcn),(int)netrue,int); MYMALLOC((dmumps_par->irn),(int)netrue,int); MYMALLOC((dmumps_par->a),(int)netrue,double2); dmumps_par->nz_alloc = (int)netrue; if (dmumps_par->nz_alloc != netrue) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); } if(dmumps_par->sym == 0){ /* if analysis already performed then we only need to read numerical values Note that we suppose that matlab did not change the internal format of the matrix between the 2 calls */ if(doanalysis){ /* || dmumps_par->info[22] == 0 */ for(i=0;i<dmumps_par->n;i++){ for(j=jcn_in[i];j<jcn_in[i+1];j++){ (dmumps_par->jcn)[j] = i+1; (dmumps_par->irn)[j] = ((int)irn_in[j])+1; } } } dmumps_par->nz = (int)ne; if( dmumps_par->nz != ne) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); #if MUMPS_ARITH == MUMPS_ARITH_z ptr_matlab = mxGetPr(A_IN); for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).r = ptr_matlab[i]; } ptr_matlab = mxGetPi(A_IN); if(ptr_matlab){ for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).i = ptr_matlab[i]; } }else{ for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).i = 0.0; } } #else ptr_matlab = mxGetPr(A_IN); for(i=0;i<dmumps_par->nz;i++){ (dmumps_par->a)[i] = ptr_matlab[i]; } #endif }else{ /* in the symmetric case we do not need to check doanalysis */ pos = 0; ptr_matlab = mxGetPr(A_IN); #if MUMPS_ARITH == MUMPS_ARITH_z ptri_matlab = mxGetPi(A_IN); #endif for(i=0;i<dmumps_par->n;i++){ for(j=jcn_in[i];j<jcn_in[i+1];j++){ if(irn_in[j] >= i){ if(pos >= netrue) mexErrMsgTxt("Input matrix must be symmetric"); (dmumps_par->jcn)[pos] = i+1; (dmumps_par->irn)[pos] = (int)irn_in[j]+1; #if MUMPS_ARITH == MUMPS_ARITH_z ((dmumps_par->a)[pos]).r = ptr_matlab[j]; if(ptri_matlab){ ((dmumps_par->a)[pos]).i = ptri_matlab[j]; }else{ ((dmumps_par->a)[pos]).i = 0.0; } #else (dmumps_par->a)[pos] = ptr_matlab[j]; #endif pos++; } } } dmumps_par->nz = pos; } EXTRACT_FROM_MATLAB_TOVAL(JOB,dmumps_par->job); EXTRACT_FROM_MATLAB_TOARR(ICNTL_IN,dmumps_par->icntl,int,40); EXTRACT_FROM_MATLAB_TOARR(CNTL_IN,dmumps_par->cntl,double,15); EXTRACT_FROM_MATLAB_TOPTR(PERM_IN,(dmumps_par->perm_in),int,((int)n)); /* colsca and rowsca are treated differently: it may happen that dmumps_par-> colsca is nonzero because it was set to a nonzero value on output (COLSCA_OUT) from MUMPS. Unfortunately if scaling was on output, one cannot currently provide scaling on input afterwards without reinitializing the instance */ EXTRACT_SCALING_FROM_MATLAB_TOPTR(COLSCA_IN,(dmumps_par->colsca),(dmumps_par->colsca_from_mumps),((int)n)); /* type always double */ EXTRACT_SCALING_FROM_MATLAB_TOPTR(ROWSCA_IN,(dmumps_par->rowsca),(dmumps_par->rowsca_from_mumps),((int)n)); /* type always double */ EXTRACT_FROM_MATLAB_TOARR(KEEP_IN,dmumps_par->keep,int,500); EXTRACT_FROM_MATLAB_TOARR(DKEEP_IN,dmumps_par->dkeep,double,230); dmumps_par->size_schur = (int)mxGetN(VAR_SCHUR); EXTRACT_FROM_MATLAB_TOPTR(VAR_SCHUR,(dmumps_par->listvar_schur),int,dmumps_par->size_schur); if(!dmumps_par->listvar_schur) dmumps_par->size_schur = 0; ptr_matlab = mxGetPr (RHS_IN); /* * To follow the "spirit" of the Matlab/Scilab interfaces, treat case of null * space separately. In that case, we initialize lrhs and nrhs, automatically * allocate the space needed, and do not rely on what is provided by the user * in component RHS, that is not touched. * * Note that, at the moment, the user should not call the solution step combined * with the factorization step when he/she sets icntl[25-1] to a non-zero value. * Hence we suppose in the following that infog[28-1] is available and that we * can use it. * * For users of scilab/matlab, it would still be nice to be able to set ICNTL(25)=-1, * and use JOB=6. If we want to make such a feature available, we should * call separately job=2 and job=3 even if job=5 or 6 and set nbrhs (and allocate * space correctly) between job=2 and job=3 calls to MUMPS. * */ if ( dmumps_par->icntl[25-1] == -1 && dmumps_par->infog[28-1] > 0 ) { dmumps_par->nrhs=dmumps_par->infog[28-1]; donullspace = dosolve; } else if ( dmumps_par->icntl[25-1] > 0 && dmumps_par->icntl[25-1] <= dmumps_par->infog[28-1] ) { dmumps_par->nrhs=1; donullspace = dosolve; } else { donullspace=0; } if (donullspace) { nbrhs=dmumps_par->nrhs; ldrhs=n; dmumps_par->lrhs=(int)n; MYMALLOC((dmumps_par->rhs),((dmumps_par->n)*(dmumps_par->nrhs)),double2); } else if((!dosolve) || ptr_matlab[0] == -9999 ) { /* rhs not already provided, or not used */ /* Case where dosolve is true and ptr_matlab[0]=-9999, this could cause problems: * 1/ RHS was not initialized while it should have been * 2/ RHS was explicitely initialized to -9999 but is not allocated of the right size */ EXTRACT_CMPLX_FROM_MATLAB_TOPTR(RHS_IN,(dmumps_par->rhs),double,1); }else{
/************************************************************************** * * Debugging Support & Misc "cold" functions * ************************************************************************** */ const lm_status_t* lm_get_status(void) { if (!alloc_info) return NULL; lm_status_t* s = (lm_status_t *)MYMALLOC(sizeof(lm_status_t)); s->first_page = alloc_info->first_page; s->page_num = alloc_info->page_num; s->idx_to_id = alloc_info->idx_2_id_adj; s->alloc_blk_num = 0; s->free_blk_num = 0; s->free_blk_info = NULL; s->alloc_blk_info = NULL; rb_tree_t* rbt = &alloc_info->alloc_blks; int alloc_blk_num = rbt_size(rbt); /* Populate allocated block info */ if (alloc_blk_num) { block_info_t* ai; ai = (block_info_t*)MYMALLOC(sizeof(block_info_t) * alloc_blk_num); rb_iter_t iter, iter_e; int idx = 0; for (iter = rbt_iter_begin(rbt), iter_e = rbt_iter_end(rbt); iter != iter_e; iter = rbt_iter_inc(rbt, iter)) { rb_node_t* blk = rbt_iter_deref(iter); ai[idx].page_idx = blk->key; ai[idx].size = blk->value; ai[idx].order = alloc_info->page_info[blk->key].order; idx++; } s->alloc_blk_info = ai; s->alloc_blk_num = idx; } /* Populate free block info */ int free_blk_num = 0; int i, e; for (i = 0, e = alloc_info->max_order; i <= e; i++) { free_blk_num += rbt_size(alloc_info->free_blks + i); } if (free_blk_num) { block_info_t* fi; fi = (block_info_t*)MYMALLOC(sizeof(block_info_t) * free_blk_num); int idx = 0; int page_size_log2 = alloc_info->page_size_log2; for (i = 0, e = alloc_info->max_order; i <= e; i++) { rb_tree_t* rbt = alloc_info->free_blks + i; rb_iter_t iter, iter_e; for (iter = rbt_iter_begin(rbt), iter_e = rbt_iter_end(rbt); iter != iter_e; iter = rbt_iter_inc(rbt, iter)) { rb_node_t* nd = rbt_iter_deref(iter); fi[idx].page_idx = nd->key; fi[idx].order = alloc_info->page_info[nd->key].order; fi[idx].size = (1 << fi[idx].order) << page_size_log2; idx++; } } ASSERT(idx == free_blk_num); s->free_blk_info = fi; s->free_blk_num = idx; } return s; }
/* Initialize the page allocator, return 1 on success, 0 otherwise. */ int lm_init_page_alloc(lm_chunk_t* chunk, ljmm_opt_t* mm_opt) { if (!chunk) { /* Trunk is not yet allocated */ return 0; } if (alloc_info) { /* This function was succesfully invoked before */ return 1; } int page_num = chunk->page_num; if (unlikely(mm_opt != NULL)) { int pn = mm_opt->dbg_alloc_page_num; if (((pn > 0) && (pn > page_num)) || !pn) return 0; else if (pn > 0) { page_num = pn; } if (!bc_set_parameter(mm_opt->enable_block_cache, mm_opt->blk_cache_in_page)) { return 0; } } int alloc_sz = sizeof(lm_alloc_t) + sizeof(lm_page_t) * (page_num + 1); alloc_info = (lm_alloc_t*) MYMALLOC(alloc_sz); if (!alloc_info) { errno = ENOMEM; return 0; } alloc_info->first_page = chunk->base; alloc_info->page_num = page_num; alloc_info->page_size = chunk->page_size; alloc_info->page_size_log2 = log2_int32(chunk->page_size); /* Init the page-info */ char* p = (char*)(alloc_info + 1); int align = __alignof__(lm_page_t); p = (char*)((((intptr_t)p) + align - 1) & ~align); alloc_info->page_info = (lm_page_t*)p; int i; lm_page_t* pi = alloc_info->page_info; for (i = 0; i < page_num; i++) { pi[i].order = INVALID_ORDER; pi[i].flags = 0; } /* Init the buddy allocator */ int e; rb_tree_t* free_blks = &alloc_info->free_blks[0]; for (i = 0, e = MAX_ORDER; i < e; i++) rbt_init(&free_blks[i]); rbt_init(&alloc_info->alloc_blks); /* Determine the max order */ int max_order = 0; unsigned int bitmask; for (bitmask = 0x80000000/*2G*/, max_order = 31; bitmask; bitmask >>= 1, max_order --) { if (bitmask & page_num) break; } alloc_info->max_order = max_order; /* So, the ID of biggest block's first page is "1 << order". e.g. * Suppose the chunk contains 11 pages, which will be divided into 3 * blocks, eaching containing 1, 2 and 8 pages. The indices of these * blocks are 0, 1, 3 respectively, and their IDs are 5, 6, and 8 * respectively. In this case: * alloc_info->idx_2_id_adj == 5 == page_id(*) - page_idx(*) */ int idx_2_id_adj = (1 << max_order) - (page_num & ((1 << max_order) - 1)); alloc_info->idx_2_id_adj = idx_2_id_adj; /* Divide the chunk into blocks, smaller block first. Smaller blocks * are likely allocated and deallocated frequently. Therefore, they are * better off residing closer to data segment. */ int page_idx = 0; int order = 0; for (bitmask = 1, order = 0; bitmask != 0; bitmask = bitmask << 1, order++) { if (page_num & bitmask) { add_free_block(page_idx, order); page_idx += (1 << order); } } /*init the block cache */ bc_init(); return 1; }
static char *_tc_deflate_impl(const char *ptr, int size, int *sp, int mode){ assert(ptr && size >= 0 && sp); z_stream zs; zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; switch(mode){ case _TCZMRAW: if(deflateInit2(&zs, 5, Z_DEFLATED, -15, 7, Z_DEFAULT_STRATEGY) != Z_OK) return NULL; break; case _TCZMGZIP: if(deflateInit2(&zs, 6, Z_DEFLATED, 15 + 16, 9, Z_DEFAULT_STRATEGY) != Z_OK) return NULL; break; default: if(deflateInit2(&zs, 6, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY) != Z_OK) return NULL; break; } int asiz = size + 16; if(asiz < ZLIBBUFSIZ) asiz = ZLIBBUFSIZ; char *buf; if(!(buf = MYMALLOC(asiz))){ deflateEnd(&zs); return NULL; } unsigned char obuf[ZLIBBUFSIZ]; int bsiz = 0; zs.next_in = (unsigned char *)ptr; zs.avail_in = size; zs.next_out = obuf; zs.avail_out = ZLIBBUFSIZ; int rv; while((rv = deflate(&zs, Z_FINISH)) == Z_OK){ int osiz = ZLIBBUFSIZ - zs.avail_out; if(bsiz + osiz > asiz){ asiz = asiz * 2 + osiz; char *swap; if(!(swap = MYREALLOC(buf, asiz))){ MYFREE(buf); deflateEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; zs.next_out = obuf; zs.avail_out = ZLIBBUFSIZ; } if(rv != Z_STREAM_END){ MYFREE(buf); deflateEnd(&zs); return NULL; } int osiz = ZLIBBUFSIZ - zs.avail_out; if(bsiz + osiz + 1 > asiz){ asiz = asiz * 2 + osiz; char *swap; if(!(swap = MYREALLOC(buf, asiz))){ MYFREE(buf); deflateEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; buf[bsiz] = '\0'; if(mode == _TCZMRAW) bsiz++; *sp = bsiz; deflateEnd(&zs); return buf; }
static char *_tc_bzdecompress_impl(const char *ptr, int size, int *sp){ assert(ptr && size >= 0 && sp); bz_stream zs; zs.bzalloc = NULL; zs.bzfree = NULL; zs.opaque = NULL; if(BZ2_bzDecompressInit(&zs, 0, 0) != BZ_OK) return NULL; int asiz = size * 2 + 16; if(asiz < BZIPBUFSIZ) asiz = BZIPBUFSIZ; char *buf; if(!(buf = MYMALLOC(asiz))){ BZ2_bzDecompressEnd(&zs); return NULL; } char obuf[BZIPBUFSIZ]; int bsiz = 0; zs.next_in = (char *)ptr; zs.avail_in = size; zs.next_out = obuf; zs.avail_out = BZIPBUFSIZ; int rv; while((rv = BZ2_bzDecompress(&zs)) == BZ_OK){ int osiz = BZIPBUFSIZ - zs.avail_out; if(bsiz + osiz >= asiz){ asiz = asiz * 2 + osiz; char *swap; if(!(swap = MYREALLOC(buf, asiz))){ MYFREE(buf); BZ2_bzDecompressEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; zs.next_out = obuf; zs.avail_out = BZIPBUFSIZ; } if(rv != BZ_STREAM_END){ MYFREE(buf); BZ2_bzDecompressEnd(&zs); return NULL; } int osiz = BZIPBUFSIZ - zs.avail_out; if(bsiz + osiz >= asiz){ asiz = asiz * 2 + osiz; char *swap; if(!(swap = MYREALLOC(buf, asiz))){ MYFREE(buf); BZ2_bzDecompressEnd(&zs); return NULL; } buf = swap; } memcpy(buf + bsiz, obuf, osiz); bsiz += osiz; buf[bsiz] = '\0'; *sp = bsiz; BZ2_bzDecompressEnd(&zs); return buf; }