diff --git a/arch/arm/src/sam34/Kconfig b/arch/arm/src/sam34/Kconfig index 862b381418..692bfd062f 100644 --- a/arch/arm/src/sam34/Kconfig +++ b/arch/arm/src/sam34/Kconfig @@ -247,6 +247,7 @@ config ARCH_CHIP_SAM4CM default n select ARCH_HAVE_MULTICPU select ARCH_HAVE_TICKLESS + select ARCH_GLOBAL_IRQDISABLE config ARCH_CHIP_SAM4L bool diff --git a/libc/misc/lib_ncompress.c b/libc/misc/lib_ncompress.c new file mode 100644 index 0000000000..8f8b116ebc --- /dev/null +++ b/libc/misc/lib_ncompress.c @@ -0,0 +1,985 @@ + +/**************************************************************************** + * libc/misc/lib_ncompress.c + * File compression ala IEEE Computer, Mar 1992. + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This is the file compress24.c extracted from the ncompress-4.2.4 release + * and adapted for NuttX. The original code was released into the public + * domain. This NuttX version is re-released under the standard NuttX + * BSD 3-clause license. The original authors are listed below: + * + * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) + * Jim McKie (decvax!mcvax!jim) + * Steve Davies (decvax!vax135!petsd!peora!srd) + * Ken Turkowski (decvax!decwrl!turtlevax!ken) + * James A. Woods (decvax!ihnp4!ames!jaw) + * Joe Orost (decvax!vax135!petsd!joe) + * Dave Mack (csu@alembic.acs.com) + * Peter Jannesen, Network Communication Systems + * (peter@ncs.nl) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RECURSIVE 1 + +#ifdef __STDC__ +# define ARGS(a) a +#else +# define ARGS(a) () +#endif + +#define LARGS(a) () /* Relay on include files for libary func defs. + */ + +#ifndef SIG_TYPE +# define SIG_TYPE void (*)() +#endif + +#define MARK(a) { asm(" .globl M.a"); asm("M.a:"); } + +#undef min +#define min(a,b) ((a>b) ? b : a) + +#ifndef IBUFSIZ +# define IBUFSIZ BUFSIZ /* Defailt input buffer size */ +#endif +#ifndef OBUFSIZ +# define OBUFSIZ BUFSIZ /* Default output buffer size */ +#endif + +#define MAXPATHLEN 1024 /* MAXPATHLEN - maximum length of a pathname we + * allow */ +#define SIZE_INNER_LOOP 256 /* Size of the inter (fast) compress loop */ + + /* Defines for third byte of header */ +#define MAGIC_1 (char_type)'\037' /* First byte of compressed file */ +#define MAGIC_2 (char_type)'\235' /* Second byte of compressed file */ +#define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */ + /* Masks 0x20 and 0x40 are free. */ + /* I think 0x20 should mean that there is */ + /* a fourth header byte (for expansion). */ +#define BLOCK_MODE 0x80 /* Block compresssion if table is full and */ + /* compression rate is dropping flush tables */ + + /* the next two codes should not be changed lightly, as they must not */ + /* lie within the contiguous general code space. */ +#define FIRST 257 /* first free entry */ +#define CLEAR 256 /* table clear output code */ + +#define INIT_BITS 9 /* initial number of bits/code */ + +#ifndef SACREDMEM + /* + * SACREDMEM is the amount of physical memory saved for others; compress + * will hog the rest. + */ +# define SACREDMEM 0 +#endif + +#ifndef USERMEM + /* + * Set USERMEM to the maximum amount of physical user memory available + * in bytes. USERMEM is used to determine the maximum BITS that can be used + * for compression. + */ +# define USERMEM 450000 /* default user memory */ +#endif + +#ifndef BYTEORDER +# define BYTEORDER 0000 +#endif + +#ifndef NOALLIGN +# define NOALLIGN 0 +#endif + +/* + * machine variants which require cc -Dmachine: pdp11, z8000, DOS + */ + +#ifdef interdata /* Perkin-Elmer */ +# define SIGNED_COMPARE_SLOW /* signed compare is slower than unsigned */ +#endif + +#ifdef pdp11 /* PDP11: don't forget to compile with -i */ +# define BITS 12 /* max bits/code for 16-bit machine */ +# define NO_UCHAR /* also if "unsigned char" functions as signed + * char */ +#endif /* pdp11 */ + +#ifdef z8000 /* Z8000: */ +# define BITS 12 /* 16-bits processor max 12 bits */ +# undef vax /* weird preprocessor */ +#endif /* z8000 */ + +#ifdef DOS /* PC/XT/AT (8088) processor */ +# define BITS 16 /* 16-bits processor max 12 bits */ +# if BITS == 16 +# define MAXSEG_64K +# endif +# undef BYTEORDER +# define BYTEORDER 4321 +# undef NOALLIGN +# define NOALLIGN 1 +#endif /* DOS */ + +#ifndef O_BINARY +# define O_BINARY 0 /* System has no binary mode */ +#endif + +#ifdef M_XENIX /* Stupid compiler can't handle arrays with */ +# if BITS == 16 /* more than 65535 bytes - so we fake it */ +# define MAXSEG_64K +# else +# if BITS > 13 /* Code only handles BITS = 12, 13, or 16 */ +# define BITS 13 +# endif +# endif +#endif + +#ifndef BITS /* General processor calculate BITS */ +# if USERMEM >= (800000+SACREDMEM) +# define FAST +# else +# if USERMEM >= (433484+SACREDMEM) +# define BITS 16 +# else +# if USERMEM >= (229600+SACREDMEM) +# define BITS 15 +# else +# if USERMEM >= (127536+SACREDMEM) +# define BITS 14 +# else +# if USERMEM >= (73464+SACREDMEM) +# define BITS 13 +# else +# define BITS 12 +# endif +# endif +# endif +# endif +# endif +#endif /* BITS */ + +#ifdef FAST +# define HBITS 17 /* 50% occupancy */ +# define HSIZE (1<>3]) |= ((long)(c))<<((o)&0x7);\ + (o) += (n); \ + } +#else +# ifdef BYTEORDER +# define output(b,o,c,n) { char_type *p = &(b)[(o)>>3]; \ + union bytes i; \ + i.word = ((long)(c))<<((o)&0x7); \ + p[0] |= i.bytes.b1; \ + p[1] |= i.bytes.b2; \ + p[2] |= i.bytes.b3; \ + (o) += (n); \ + } +# else +# define output(b,o,c,n) { char_type *p = &(b)[(o)>>3]; \ + long i = ((long)(c))<<((o)&0x7); \ + p[0] |= (char_type)(i); \ + p[1] |= (char_type)(i>>8); \ + p[2] |= (char_type)(i>>16); \ + (o) += (n); \ + } +# endif +#endif +#if BYTEORDER == 4321 && NOALLIGN == 1 +# define input(b,o,c,n,m){ \ + (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \ + (o) += (n); \ + } +#else +# define input(b,o,c,n,m){ char_type *p = &(b)[(o)>>3]; \ + (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \ + ((long)(p[2])<<16))>>((o)&0x7))&(m); \ + (o) += (n); \ + } +#endif + +char *progname; /* Program name */ +int silent = 0; /* don't tell me about errors */ +int quiet = 1; /* don't tell me about compression */ +int do_decomp = 0; /* Decompress mode */ +int force = 0; /* Force overwrite of files and links */ +int nomagic = 0; /* Use a 3-byte magic number header, */ + /* unless old file */ +int block_mode = BLOCK_MODE; /* Block compress mode -C compatible with 2.0 */ +int maxbits = BITS; /* user settable max # bits/code */ +int zcat_flg = 0; /* Write output on stdout, suppress messages */ +int recursive = 0; /* compress directories */ +int exit_code = -1; /* Exitcode of compress (-1 no file compressed) + */ + +char_type inbuf[IBUFSIZ + 64]; /* Input buffer */ +char_type outbuf[OBUFSIZ + 2048]; /* Output buffer */ + +struct stat infstat; /* Input file status */ +char *ifname; /* Input filename */ +int remove_ofname = 0; /* Remove output file on a error */ +char ofname[MAXPATHLEN]; /* Output filename */ +int fgnd_flag = 0; /* Running in background (SIGINT=SIGIGN) */ + +long bytes_in; /* Total number of byte from input */ +long bytes_out; /* Total number of byte to output */ + +/* + * To save much memory, we overlay the table used by compress() with those + * used by decompress(). The tab_prefix table is the same size and type + * as the codetab. The tab_suffix table needs 2**BITS characters. We + * get this from the beginning of htab. The output stack uses the rest + * of htab, and contains characters. There is plenty of room for any + * possible stack (stack used to be 8000 characters). + */ +#ifdef MAXSEG_64K +count_int htab0[8192]; +count_int htab1[8192]; +count_int htab2[8192]; +count_int htab3[8192]; +count_int htab4[8192]; +count_int htab5[8192]; +count_int htab6[8192]; +count_int htab7[8192]; +count_int htab8[HSIZE - 65536]; +count_int *htab[9] = + { htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 }; + +unsigned short code0tab[16384]; +unsigned short code1tab[16384]; +unsigned short code2tab[16384]; +unsigned short code3tab[16384]; +unsigned short code4tab[16384]; +unsigned short *codetab[5] = + { code0tab, code1tab, code2tab, code3tab, code4tab }; + +# define htabof(i) (htab[(i) >> 13][(i) & 0x1fff]) +# define codetabof(i) (codetab[(i) >> 14][(i) & 0x3fff]) +# define tab_prefixof(i) codetabof(i) +# define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff] +# define de_stack ((char_type *)(&htab2[8191])) +void clear_htab() +{ + memset(htab0, -1, sizeof(htab0)); + memset(htab1, -1, sizeof(htab1)); + memset(htab2, -1, sizeof(htab2)); + memset(htab3, -1, sizeof(htab3)); + memset(htab4, -1, sizeof(htab4)); + memset(htab5, -1, sizeof(htab5)); + memset(htab6, -1, sizeof(htab6)); + memset(htab7, -1, sizeof(htab7)); + memset(htab8, -1, sizeof(htab8)); +} + +# define clear_tab_prefixof() memset(code0tab, 0, 256); +#else /* Normal machine */ +count_int htab[HSIZE]; +unsigned short codetab[HSIZE]; + +# define htabof(i) htab[i] +# define codetabof(i) codetab[i] +# define tab_prefixof(i) codetabof(i) +# define tab_suffixof(i) ((char_type *)(htab))[i] +# define de_stack ((char_type *)&(htab[HSIZE-1])) +# define clear_htab() memset(htab, -1, sizeof(htab)) +# define clear_tab_prefixof() memset(codetab, 0, 256); + +# ifdef FAST +int primetab[256] = /* Special secudary hash table. */ +{ + 1013, -1061, 1109, -1181, 1231, -1291, 1361, -1429, + 1481, -1531, 1583, -1627, 1699, -1759, 1831, -1889, + 1973, -2017, 2083, -2137, 2213, -2273, 2339, -2383, + 2441, -2531, 2593, -2663, 2707, -2753, 2819, -2887, + 2957, -3023, 3089, -3181, 3251, -3313, 3361, -3449, + 3511, -3557, 3617, -3677, 3739, -3821, 3881, -3931, + 4013, -4079, 4139, -4219, 4271, -4349, 4423, -4493, + 4561, -4639, 4691, -4783, 4831, -4931, 4973, -5023, + 5101, -5179, 5261, -5333, 5413, -5471, 5521, -5591, + 5659, -5737, 5807, -5857, 5923, -6029, 6089, -6151, + 6221, -6287, 6343, -6397, 6491, -6571, 6659, -6709, + 6791, -6857, 6917, -6983, 7043, -7129, 7213, -7297, + 7369, -7477, 7529, -7577, 7643, -7703, 7789, -7873, + 7933, -8017, 8093, -8171, 8237, -8297, 8387, -8461, + 8543, -8627, 8689, -8741, 8819, -8867, 8963, -9029, + 9109, -9181, 9241, -9323, 9397, -9439, 9511, -9613, + 9677, -9743, 9811, -9871, 9941, -10061, 10111, -10177, + 10259, -10321, 10399, -10477, 10567, -10639, 10711, -10789, + 10867, -10949, 11047, -11113, 11173, -11261, 11329, -11423, + 11491, -11587, 11681, -11777, 11827, -11903, 11959, -12041, + 12109, -12197, 12263, -12343, 12413, -12487, 12541, -12611, + 12671, -12757, 12829, -12917, 12979, -13043, 13127, -13187, + 13291, -13367, 13451, -13523, 13619, -13691, 13751, -13829, + 13901, -13967, 14057, -14153, 14249, -14341, 14419, -14489, + 14557, -14633, 14717, -14767, 14831, -14897, 14983, -15083, + 15149, -15233, 15289, -15359, 15427, -15497, 15583, -15649, + 15733, -15791, 15881, -15937, 16057, -16097, 16189, -16267, + 16363, -16447, 16529, -16619, 16691, -16763, 16879, -16937, + 17021, -17093, 17183, -17257, 17341, -17401, 17477, -17551, + 17623, -17713, 17791, -17891, 17957, -18041, 18097, -18169, + 18233, -18307, 18379, -18451, 18523, -18637, 18731, -18803, + 18919, -19031, 19121, -19211, 19273, -19381, 19429, -19477 +}; +# endif + +/* + * compress fdin to fdout + * + * Algorithm: use open addressing double hashing (no chaining) on the + * prefix code / next character combination. We do a variant of Knuth's + * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime + * secondary probe. Here, the modular division first probe is gives way + * to a faster exclusive-or manipulation. Also do block compression with + * an adaptive reset, whereby the code table is cleared when the compression + * ratio decreases, but after the table fills. The variable-length output + * codes are re-sized at this point, and a special CLEAR code is generated + * for the decompressor. Late addition: construct the table according to + * file size for noticeable speed improvement on small files. Please direct + * questions about this implementation to ames!jaw. + */ +void compress(int fdin, int fdout) +{ + long hp; + int rpos; + long fc; + int outbits; + int rlop; + int rsize; + int stcode; + code_int free_ent; + int boff; + int n_bits; + int ratio; + long checkpoint; + code_int extcode; + union + { + long code; + struct + { + char_type c; + unsigned short ent; + } e; + } fcode; + + ratio = 0; + checkpoint = CHECK_GAP; + extcode = MAXCODE(n_bits = INIT_BITS) + 1; + stcode = 1; + free_ent = FIRST; + + memset(outbuf, 0, sizeof(outbuf)); + bytes_out = 0; + bytes_in = 0; + outbuf[0] = MAGIC_1; + outbuf[1] = MAGIC_2; + outbuf[2] = (char)(maxbits | block_mode); + boff = outbits = (3 << 3); + fcode.code = 0; + + clear_htab(); + + while ((rsize = read(fdin, inbuf, IBUFSIZ)) > 0) + { + if (bytes_in == 0) + { + fcode.e.ent = inbuf[0]; + rpos = 1; + } + else + rpos = 0; + + rlop = 0; + + do + { + if (free_ent >= extcode && fcode.e.ent < FIRST) + { + if (n_bits < maxbits) + { + boff = outbits = (outbits - 1) + ((n_bits << 3) - + ((outbits - boff - 1 + + (n_bits << 3)) % + (n_bits << 3))); + if (++n_bits < maxbits) + extcode = MAXCODE(n_bits) + 1; + else + extcode = MAXCODE(n_bits); + } + else + { + extcode = MAXCODE(16) + OBUFSIZ; + stcode = 0; + } + } + + if (!stcode && bytes_in >= checkpoint && fcode.e.ent < FIRST) + { + long int rat; + + checkpoint = bytes_in + CHECK_GAP; + + if (bytes_in > 0x007fffff) + { /* shift will overflow */ + rat = (bytes_out + (outbits >> 3)) >> 8; + + if (rat == 0) /* Don't divide by zero */ + rat = 0x7fffffff; + else + rat = bytes_in / rat; + } + else + rat = (bytes_in << 8) / (bytes_out + (outbits >> 3)); /* 8 + * fractional + * bits + */ + if (rat >= ratio) + ratio = (int)rat; + else + { + ratio = 0; + clear_htab(); + output(outbuf, outbits, CLEAR, n_bits); + boff = outbits = (outbits - 1) + ((n_bits << 3) - + ((outbits - boff - 1 + + (n_bits << 3)) % + (n_bits << 3))); + extcode = MAXCODE(n_bits = INIT_BITS) + 1; + free_ent = FIRST; + stcode = 1; + } + } + + if (outbits >= (OBUFSIZ << 3)) + { + if (write(fdout, outbuf, OBUFSIZ) != OBUFSIZ) + write_error(); + + outbits -= (OBUFSIZ << 3); + boff = -(((OBUFSIZ << 3) - boff) % (n_bits << 3)); + bytes_out += OBUFSIZ; + + memcpy(outbuf, outbuf + OBUFSIZ, (outbits >> 3) + 1); + memset(outbuf + (outbits >> 3) + 1, '\0', OBUFSIZ); + } + + { + int i; + + i = rsize - rlop; + + if ((code_int) i > extcode - free_ent) + i = (int)(extcode - free_ent); + if (i > ((sizeof(outbuf) - 32) * 8 - outbits) / n_bits) + i = ((sizeof(outbuf) - 32) * 8 - outbits) / n_bits; + + if (!stcode && (long)i > checkpoint - bytes_in) + i = (int)(checkpoint - bytes_in); + + rlop += i; + bytes_in += i; + } + + goto next; + hfound:fcode.e.ent = codetabof(hp); + next:if (rpos >= rlop) + goto endlop; + next2:fcode.e.c = inbuf[rpos++]; +# ifndef FAST + { + code_int i; + fc = fcode.code; + + hp = (((long)(fcode.e.c)) << (BITS - 8)) ^ (long)(fcode.e.ent); + + if ((i = htabof(hp)) == fc) + goto hfound; + + if (i != -1) + { + long disp; + + disp = (HSIZE - hp) - 1; /* secondary hash (after G. + * Knott) */ + + do + { + if ((hp -= disp) < 0) + hp += HSIZE; + + if ((i = htabof(hp)) == fc) + goto hfound; + } + while (i != -1); + } + } +# else + { + long i; + long p; + fc = fcode.code; + + hp = ((((long)(fcode.e.c)) << (HBITS - 8)) ^ (long)(fcode.e.ent)); + + if ((i = htabof(hp)) == fc) + goto hfound; + if (i == -1) + goto out; + + p = primetab[fcode.e.c]; + lookup:hp = (hp + p) & HMASK; + if ((i = htabof(hp)) == fc) + goto hfound; + if (i == -1) + goto out; + hp = (hp + p) & HMASK; + if ((i = htabof(hp)) == fc) + goto hfound; + if (i == -1) + goto out; + hp = (hp + p) & HMASK; + if ((i = htabof(hp)) == fc) + goto hfound; + if (i == -1) + goto out; + goto lookup; + } + out:; +# endif + output(outbuf, outbits, fcode.e.ent, n_bits); + + { + long fc = fcode.code; + fcode.e.ent = fcode.e.c; + + if (stcode) + { + codetabof(hp) = (unsigned short)free_ent++; + htabof(hp) = fc; + } + } + + goto next; + + endlop:if (fcode.e.ent >= FIRST && rpos < rsize) + goto next2; + + if (rpos > rlop) + { + bytes_in += rpos - rlop; + rlop = rpos; + } + } + while (rlop < rsize); + } + + if (rsize < 0) + read_error(); + + if (bytes_in > 0) + output(outbuf, outbits, fcode.e.ent, n_bits); + + if (write(fdout, outbuf, (outbits + 7) >> 3) != (outbits + 7) >> 3) + write_error(); + + bytes_out += (outbits + 7) >> 3; + + return; +} + +/* + * Decompress stdin to stdout. This routine adapts to the codes in the + * file building the "string" table on-the-fly; requiring no table to + * be stored in the compressed file. The tables used herein are shared + * with those of the compress() routine. See the definitions above. + */ + +void decompress(int fdin, int fdout) + int fdin; + int fdout; +{ + char_type *stackp; + code_int code; + int finchar; + code_int oldcode; + code_int incode; + int inbits; + int posbits; + int outpos; + int insize; + int bitmask; + code_int free_ent; + code_int maxcode; + code_int maxmaxcode; + int n_bits; + int rsize; + + bytes_in = 0; + bytes_out = 0; + insize = 0; + + while (insize < 3 && (rsize = read(fdin, inbuf + insize, IBUFSIZ)) > 0) + insize += rsize; + + if (insize < 3 || inbuf[0] != MAGIC_1 || inbuf[1] != MAGIC_2) + { + if (rsize < 0) + read_error(); + + if (insize > 0) + { + fprintf(stderr, "%s: not in compressed format\n", + (ifname[0] != '\0' ? ifname : "stdin")); + exit_code = 1; + } + + return; + } + + maxbits = inbuf[2] & BIT_MASK; + block_mode = inbuf[2] & BLOCK_MODE; + + if (maxbits > BITS) + { + fprintf(stderr, + "%s: compressed with %d bits, can only handle %d bits\n", + (*ifname != '\0' ? ifname : "stdin"), maxbits, BITS); + exit_code = 4; + return; + } + + maxmaxcode = MAXCODE(maxbits); + + bytes_in = insize; + maxcode = MAXCODE(n_bits = INIT_BITS) - 1; + bitmask = (1 << n_bits) - 1; + oldcode = -1; + finchar = 0; + outpos = 0; + posbits = 3 << 3; + + free_ent = ((block_mode) ? FIRST : 256); + + clear_tab_prefixof(); /* As above, initialize the first 256 entries + * in the table. */ + + for (code = 255; code >= 0; --code) + tab_suffixof(code) = (char_type) code; + + do + { + resetbuf:; + { + int i; + int e; + int o; + + o = posbits >> 3; + e = o <= insize ? insize - o : 0; + + for (i = 0; i < e; ++i) + inbuf[i] = inbuf[i + o]; + + insize = e; + posbits = 0; + } + + if (insize < sizeof(inbuf) - IBUFSIZ) + { + if ((rsize = read(fdin, inbuf + insize, IBUFSIZ)) < 0) + read_error(); + + insize += rsize; + } + + inbits = ((rsize > 0) ? (insize - insize % n_bits) << 3 : + (insize << 3) - (n_bits - 1)); + + while (inbits > posbits) + { + if (free_ent > maxcode) + { + posbits = ((posbits - 1) + ((n_bits << 3) - + (posbits - 1 + + (n_bits << 3)) % (n_bits << 3))); + + ++n_bits; + if (n_bits == maxbits) + maxcode = maxmaxcode; + else + maxcode = MAXCODE(n_bits) - 1; + + bitmask = (1 << n_bits) - 1; + goto resetbuf; + } + + input(inbuf, posbits, code, n_bits, bitmask); + + if (oldcode == -1) + { + if (code >= 256) + { + fprintf(stderr, "oldcode:-1 code:%i\n", (int)(code)); + fprintf(stderr, "uncompress: corrupt input\n"); + abort_compress(); + } + outbuf[outpos++] = (char_type) (finchar = (int)(oldcode = code)); + continue; + } + + if (code == CLEAR && block_mode) + { + clear_tab_prefixof(); + free_ent = FIRST - 1; + posbits = ((posbits - 1) + ((n_bits << 3) - + (posbits - 1 + + (n_bits << 3)) % (n_bits << 3))); + maxcode = MAXCODE(n_bits = INIT_BITS) - 1; + bitmask = (1 << n_bits) - 1; + goto resetbuf; + } + + incode = code; + stackp = de_stack; + + if (code >= free_ent) /* Special case for KwKwK string. */ + { + if (code > free_ent) + { + char_type *p; + + posbits -= n_bits; + p = &inbuf[posbits >> 3]; + + fprintf(stderr, + "insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)\n", + insize, posbits, p[-1], p[0], p[1], p[2], p[3], + (posbits & 07)); + fprintf(stderr, "uncompress: corrupt input\n"); + abort_compress(); + } + + *--stackp = (char_type) finchar; + code = oldcode; + } + + while ((cmp_code_int) code >= (cmp_code_int) 256) + { /* Generate output characters in reverse order */ + *--stackp = tab_suffixof(code); + code = tab_prefixof(code); + } + + *--stackp = (char_type) (finchar = tab_suffixof(code)); + + /* And put them out in forward order */ + + { + int i; + + if (outpos + (i = (de_stack - stackp)) >= OBUFSIZ) + { + do + { + if (i > OBUFSIZ - outpos) + i = OBUFSIZ - outpos; + + if (i > 0) + { + memcpy(outbuf + outpos, stackp, i); + outpos += i; + } + + if (outpos >= OBUFSIZ) + { + if (write(fdout, outbuf, outpos) != outpos) + write_error(); + + outpos = 0; + } + stackp += i; + } + while ((i = (de_stack - stackp)) > 0); + } + else + { + memcpy(outbuf + outpos, stackp, i); + outpos += i; + } + } + + if ((code = free_ent) < maxmaxcode) /* Generate the new entry. */ + { + tab_prefixof(code) = (unsigned short)oldcode; + tab_suffixof(code) = (char_type) finchar; + free_ent = code + 1; + } + + oldcode = incode; /* Remember previous code. */ + } + + bytes_in += rsize; + } + while (rsize > 0); + + if (outpos > 0 && write(fdout, outbuf, outpos) != outpos) + write_error(); +} + +void read_error() +{ + fprintf(stderr, "\nread error on"); + perror((ifname[0] != '\0') ? ifname : "stdin"); + abort_compress(); +} + +void write_error() +{ + fprintf(stderr, "\nwrite error on"); + perror((ofname[0] != '\0') ? ofname : "stdout"); + abort_compress(); +} + +void abort_compress() +{ + if (remove_ofname) + unlink(ofname); + + exit(1); +} + +void prratio(stream, num, den) + FILE *stream; + long int num; + long int den; +{ + int q; + + if (den > 0) + { + if (num > 214748L) + q = (int)(num / (den / 10000L)); /* 2147483647/10000 */ + else + q = (int)(10000L * num / den); /* Long calculations, though */ + } + else + q = 10000; + + if (q < 0) + { + putc('-', stream); + q = -q; + } + + fprintf(stream, "%d.%02d%%", q / 100, q % 100); +} diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs index c9088453c0..7bacba7b0f 100644 --- a/sched/sched/Make.defs +++ b/sched/sched/Make.defs @@ -100,6 +100,7 @@ endif ifeq ($(CONFIG_SMP),y) CSRCS += sched_tasklistlock.c +CSRCS += sched_thistask.c endif # Include sched build support diff --git a/sched/sched/sched.h b/sched/sched/sched.h index 63c081de85..cad10c8d94 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -72,6 +72,7 @@ /* These are macros to access the current CPU and the current task on a CPU. * These macros are intended to support a future SMP implementation. + * NOTE: this_task() for SMP is implemented in sched_thistask.c */ #ifdef CONFIG_SMP @@ -80,8 +81,8 @@ #else # define current_task(cpu) ((FAR struct tcb_s *)g_readytorun.head) # define this_cpu() (0) +# define this_task() (current_task(this_cpu())) #endif -#define this_task() (current_task(this_cpu())) /* List attribute flags */ @@ -427,6 +428,8 @@ void sched_sporadic_lowpriority(FAR struct tcb_s *tcb); #endif #ifdef CONFIG_SMP +FAR struct tcb_s *this_task(void); + int sched_cpu_select(cpu_set_t affinity); int sched_cpu_pause(FAR struct tcb_s *tcb); diff --git a/sched/sched/sched_thistask.c b/sched/sched/sched_thistask.c new file mode 100644 index 0000000000..59237de3be --- /dev/null +++ b/sched/sched/sched_thistask.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * sched/sched/sched_thistask.c + * + * Copyright (C) 2018 Sony Corporation. All rights reserved. + * Author: Masayuki Ishikawa + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +#include "sched/sched.h" + +#ifdef CONFIG_SMP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: this_task + * + * Description: + * The functions will safely obtain the TCB that is currently running + * on the current CPU. In SMP, this must be done by disabling local + * interrupts to avoid CPU switching during access to current_task() + * + * Return Value: + * the TCB that is currently running on the current CPU. + * + ****************************************************************************/ + +FAR struct tcb_s *this_task(void) +{ + irqstate_t flags; + FAR struct tcb_s *tcb; + +#ifdef CONDIF_ARCH_GLOBAL_IRQDISABLE + /* Disable local interrupts to avoid CPU switching */ + + flags = up_irq_save(); +#else + /* Enter a critical section */ + + flags = enter_critical_section(); +#endif + + /* Obtain the TCB which is currently running on this CPU */ + + tcb = current_task(this_cpu()); + + /* Enable local interrupts */ + +#ifdef CONDIF_ARCH_GLOBAL_IRQDISABLE + up_irq_restore(flags); +#else + leave_critical_section(flags); +#endif + return tcb; +} + +#endif /* CONFIG_SMP */