188 lines
4.6 KiB
C
188 lines
4.6 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these librararies and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
|
|
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
|
|
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
|
//%% (c) Copyright 1993, 1994 Novell, Inc.
|
|
//%% $XConsortium: api_storage.C /main/3 1995/10/23 09:54:55 rswiston $
|
|
/*
|
|
*
|
|
* api_storage.cc
|
|
*
|
|
* Copyright (c) 1990 by Sun Microsystems, Inc.
|
|
*
|
|
* implementation of api storage classes
|
|
*
|
|
* NOTE: this implementation is rather over-abstract, using the
|
|
* generic list classes to manage the stack. If this turns out
|
|
* to be too expensive, a very simple array-of-void* could
|
|
* be used; the marks could just be special entries (since malloc()
|
|
* always returns addresses on a doubleword boundary, any void* that's
|
|
* not a multiple of 8 would be distinguishable.) The only problem would
|
|
* be growing the array when out of room.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "api/c/api_storage.h"
|
|
|
|
_Tt_api_stg_stack::
|
|
_Tt_api_stg_stack(){
|
|
mark_counter = 0;
|
|
stack = new _Tt_api_stg_stack_elm_list;
|
|
}
|
|
|
|
_Tt_api_stg_stack::
|
|
~_Tt_api_stg_stack(){
|
|
}
|
|
|
|
int _Tt_api_stg_stack::
|
|
mark()
|
|
{
|
|
int result = ++mark_counter;
|
|
_Tt_api_stg_stack_elm_ptr e = new _Tt_api_stg_stack_elm;
|
|
|
|
e->entry_type = _Tt_api_stg_stack_elm::STACK_MARK;
|
|
e->addr = (caddr_t) (intptr_t) result;
|
|
stack->push(e);
|
|
return result;
|
|
}
|
|
|
|
void _Tt_api_stg_stack::
|
|
release(int mark)
|
|
{
|
|
// it's tempting to just pop and free until we get to the
|
|
// matching mark, but that would be terrible if the mark
|
|
// didn't exist (e.g. two releases for the same mark):
|
|
// we'd free *everything*.
|
|
|
|
_Tt_api_stg_stack_elm_list_cursor c(stack);
|
|
int found = 0;
|
|
|
|
while(!found && c.next()) {
|
|
if (c->entry_type == _Tt_api_stg_stack_elm::STACK_MARK)
|
|
/* It is better to promote mark to caddr_t than to demote addr
|
|
field for a 64 bit arch */
|
|
if (c->addr == (caddr_t) (intptr_t) mark) {
|
|
found = 1;
|
|
}
|
|
}
|
|
if (!found) return;
|
|
do {
|
|
if (c->entry_type == _Tt_api_stg_stack_elm::STACK_STORAGE) {
|
|
::free((MALLOCTYPE *)c->addr);
|
|
}
|
|
c.remove();
|
|
} while(c.prev());
|
|
return;
|
|
}
|
|
|
|
caddr_t _Tt_api_stg_stack::
|
|
#ifdef _DEBUG_MALLOC_INC
|
|
debug_malloc(char *fname, int lnum, size_t size)
|
|
#else
|
|
malloc(size_t size)
|
|
#endif
|
|
{
|
|
caddr_t p = (caddr_t)::malloc(size);
|
|
if (p==0) return p;
|
|
|
|
_Tt_api_stg_stack_elm_ptr e = new _Tt_api_stg_stack_elm;
|
|
e->entry_type = _Tt_api_stg_stack_elm::STACK_STORAGE;
|
|
e->addr = p;
|
|
stack->push(e);
|
|
return p;
|
|
}
|
|
|
|
caddr_t _Tt_api_stg_stack::
|
|
take(caddr_t addr)
|
|
{
|
|
_Tt_api_stg_stack_elm_ptr e = new _Tt_api_stg_stack_elm;
|
|
e->entry_type = _Tt_api_stg_stack_elm::STACK_STORAGE;
|
|
e->addr = addr;
|
|
stack->push(e);
|
|
return addr;
|
|
}
|
|
|
|
void _Tt_api_stg_stack::
|
|
#ifdef _DEBUG_MALLOC_INC
|
|
debug_free(char *fname, int lnum, caddr_t addr)
|
|
#else
|
|
free(caddr_t addr)
|
|
#endif
|
|
{
|
|
_Tt_api_stg_stack_elm_list_cursor c(stack);
|
|
|
|
while(c.prev()) {
|
|
if (c->entry_type == _Tt_api_stg_stack_elm::STACK_STORAGE)
|
|
if (c->addr == addr) {
|
|
::free((MALLOCTYPE *)c->addr);
|
|
c.remove();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
_tt_api_stg_stack_elm_print(FILE *fs, const _Tt_object *obj)
|
|
{
|
|
((_Tt_api_stg_stack_elm *)obj)->print(fs);
|
|
}
|
|
|
|
/*
|
|
* Print a _Tt_api_stg_stack
|
|
void _Tt_api_stg_stack::
|
|
print(FILE *f) const
|
|
{
|
|
(void)fprintf(f,"_Tt_api_stg_stack at %lx <\n",this);
|
|
(void)fprintf(f,"mark_counter: %d\n",mark_counter);
|
|
stack->print(_tt_api_stg_stack_elm_print);
|
|
(void)fprintf(f,"> _Tt_api_stg_stack at %lx\n",this);
|
|
}
|
|
*/
|
|
|
|
_Tt_api_stg_stack_elm::
|
|
~_Tt_api_stg_stack_elm()
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Print a _Tt_api_stg_stack_elm
|
|
*/
|
|
void _Tt_api_stg_stack_elm::
|
|
print(FILE *f) const
|
|
{
|
|
|
|
(void)fprintf(f,"_Tt_api_stg_stack_elm at %p <",this);
|
|
switch (entry_type) {
|
|
case STACK_MARK:
|
|
(void)fprintf(f,"mark %p>\n",addr);
|
|
break;
|
|
case STACK_STORAGE:
|
|
(void)fprintf(f,"addr 0x%p>\n",addr);
|
|
break;
|
|
}
|
|
}
|
|
|