晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /proc/thread-self/root/usr/share/doc/python3-pycparser/examples/c_files/ |
Upload File : |
//----------------------------------------------------------------
// Statically-allocated memory manager
//
// by Eli Bendersky (eliben@gmail.com)
//
// This code is in the public domain.
//----------------------------------------------------------------
#include "memmgr.h"
typedef ulong Align;
union mem_header_union
{
struct
{
// Pointer to the next block in the free list
//
union mem_header_union* next;
// Size of the block (in quantas of sizeof(mem_header_t))
//
ulong size;
} s;
// Used to align headers in memory to a boundary
//
Align align_dummy;
};
typedef union mem_header_union mem_header_t;
// Initial empty list
//
static mem_header_t base;
// Start of free list
//
static mem_header_t* freep = 0;
// Static pool for new allocations
//
static byte pool[POOL_SIZE] = {0};
static ulong pool_free_pos = 0;
void memmgr_init()
{
base.s.next = 0;
base.s.size = 0;
freep = 0;
pool_free_pos = 0;
}
static mem_header_t* get_mem_from_pool(ulong nquantas)
{
ulong total_req_size;
mem_header_t* h;
if (nquantas < MIN_POOL_ALLOC_QUANTAS)
nquantas = MIN_POOL_ALLOC_QUANTAS;
total_req_size = nquantas * sizeof(mem_header_t);
if (pool_free_pos + total_req_size <= POOL_SIZE)
{
h = (mem_header_t*) (pool + pool_free_pos);
h->s.size = nquantas;
memmgr_free((void*) (h + 1));
pool_free_pos += total_req_size;
}
else
{
return 0;
}
return freep;
}
// Allocations are done in 'quantas' of header size.
// The search for a free block of adequate size begins at the point 'freep'
// where the last block was found.
// If a too-big block is found, it is split and the tail is returned (this
// way the header of the original needs only to have its size adjusted).
// The pointer returned to the user points to the free space within the block,
// which begins one quanta after the header.
//
void* memmgr_alloc(ulong nbytes)
{
mem_header_t* p;
mem_header_t* prevp;
// Calculate how many quantas are required: we need enough to house all
// the requested bytes, plus the header. The -1 and +1 are there to make sure
// that if nbytes is a multiple of nquantas, we don't allocate too much
//
ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;
// First alloc call, and no free list yet ? Use 'base' for an initial
// denegerate block of size 0, which points to itself
//
if ((prevp = freep) == 0)
{
base.s.next = freep = prevp = &base;
base.s.size = 0;
}
for (p = prevp->s.next; ; prevp = p, p = p->s.next)
{
// big enough ?
if (p->s.size >= nquantas)
{
// exactly ?
if (p->s.size == nquantas)
{
// just eliminate this block from the free list by pointing
// its prev's next to its next
//
prevp->s.next = p->s.next;
}
else // too big
{
p->s.size -= nquantas;
p += p->s.size;
p->s.size = nquantas;
}
freep = prevp;
return (void*) (p + 1);
}
// Reached end of free list ?
// Try to allocate the block from the pool. If that succeeds,
// get_mem_from_pool adds the new block to the free list and
// it will be found in the following iterations. If the call
// to get_mem_from_pool doesn't succeed, we've run out of
// memory
//
else if (p == freep)
{
if ((p = get_mem_from_pool(nquantas)) == 0)
{
#ifdef DEBUG_MEMMGR_FATAL
printf("!! Memory allocation failed !!\n");
#endif
return 0;
}
}
}
}
// Scans the free list, starting at freep, looking the the place to insert the
// free block. This is either between two existing blocks or at the end of the
// list. In any case, if the block being freed is adjacent to either neighbor,
// the adjacent blocks are combined.
//
void memmgr_free(void* ap)
{
mem_header_t* block;
mem_header_t* p;
// acquire pointer to block header
block = ((mem_header_t*) ap) - 1;
// Find the correct place to place the block in (the free list is sorted by
// address, increasing order)
//
for (p = freep; !(block > p && block < p->s.next); p = p->s.next)
{
// Since the free list is circular, there is one link where a
// higher-addressed block points to a lower-addressed block.
// This condition checks if the block should be actually
// inserted between them
//
if (p >= p->s.next && (block > p || block < p->s.next))
break;
}
// Try to combine with the higher neighbor
//
if (block + block->s.size == p->s.next)
{
block->s.size += p->s.next->s.size;
block->s.next = p->s.next->s.next;
}
else
{
block->s.next = p->s.next;
}
// Try to combine with the lower neighbor
//
if (p + p->s.size == block)
{
p->s.size += block->s.size;
p->s.next = block->s.next;
}
else
{
p->s.next = block;
}
freep = p;
}