sched/sched: SMP: Fix this_task() to be an atomic operation. In the previous implementation, this_task() was defined in sched.h by using just a macro current_task(this_cpu()). However, I found that this is not atomic and actually sometimes switching CPU happened in executing the macro when we tested audio steaming plus executing commands via telnet. This change resolves this issue by implementing atomic this_task()in sched_thistask.c which is newly introduced.

This commit is contained in:
Masayuki Ishikawa 2018-02-04 16:59:09 -06:00 committed by Gregory Nutt
parent 31278bc163
commit c8a372702a
5 changed files with 1090 additions and 1 deletions

View File

@ -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

985
libc/misc/lib_ncompress.c Normal file
View File

@ -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 <gnutt@nuttx.org>
*
* 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 <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
#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<<HBITS)
# define HMASK (HSIZE-1)
# define HPRIME 9941
# define BITS 16
# undef MAXSEG_64K
#else
# if BITS == 16
# define HSIZE 69001 /* 95% occupancy */
# endif
# if BITS == 15
# define HSIZE 35023 /* 94% occupancy */
# endif
# if BITS == 14
# define HSIZE 18013 /* 91% occupancy */
# endif
# if BITS == 13
# define HSIZE 9001 /* 91% occupancy */
# endif
# if BITS <= 12
# define HSIZE 5003 /* 80% occupancy */
# endif
#endif
#define CHECK_GAP 10000
typedef long int code_int;
#ifdef SIGNED_COMPARE_SLOW
typedef unsigned long int count_int;
typedef unsigned short int count_short;
typedef unsigned long int cmp_code_int; /* Cast to make compare faster */
#else
typedef long int count_int;
typedef long int cmp_code_int;
#endif
typedef unsigned char char_type;
#define ARGVAL() (*++(*argv) || (--argc && *++argv))
#define MAXCODE(n) (1L << (n))
union bytes
{
long word;
struct
{
#if BYTEORDER == 4321
char_type b1;
char_type b2;
char_type b3;
char_type b4;
#else
# if BYTEORDER == 1234
char_type b4;
char_type b3;
char_type b2;
char_type b1;
# else
# undef BYTEORDER
int dummy;
# endif
#endif
} bytes;
};
#if BYTEORDER == 4321 && NOALLIGN == 1
# define output(b,o,c,n) { \
*(long *)&((b)[(o)>>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);
}

View File

@ -100,6 +100,7 @@ endif
ifeq ($(CONFIG_SMP),y)
CSRCS += sched_tasklistlock.c
CSRCS += sched_thistask.c
endif
# Include sched build support

View File

@ -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);

View File

@ -0,0 +1,99 @@
/****************************************************************************
* sched/sched/sched_thistask.c
*
* Copyright (C) 2018 Sony Corporation. All rights reserved.
* Author: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
* Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <nuttx/spinlock.h>
#include <sys/types.h>
#include <arch/irq.h>
#include <nuttx/irq.h>
#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 */