URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk/gdb-5.0/gdb/osf-share
- from Rev 107 to Rev 1765
- ↔ Reverse comparison
Rev 107 → Rev 1765
/cma_tcb_defs.h
0,0 → 1,269
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* TCB-related type definitions. |
*/ |
|
#ifndef CMA_TCB_DEFS |
#define CMA_TCB_DEFS |
|
/* |
* INCLUDE FILES |
*/ |
# if !_CMA_THREAD_SYNC_IO_ |
# include <cma_thread_io.h> |
# endif |
#include <cma.h> |
#include <cma_debug_client.h> |
#include <cma_attr.h> |
#include <cma_defs.h> |
#include <cma_handle.h> |
#include <cma_queue.h> |
#if _CMA_OS_ == _CMA__UNIX |
# if defined(SNI_DCOSX) |
# include <sys/ucontext.h> |
# endif |
# include <signal.h> |
#endif |
#include <cma_sched.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX |
# define cma__c_ibmr2_ctx_stack_size 2048 |
# define cma__c_ibmr2_ctx_stack_top (cma__c_ibmr2_ctx_stack_size - 1) |
#endif |
|
/* |
* TYPEDEFS |
*/ |
|
#ifndef __STDC__ |
# if _CMA_HARDWARE_ != _CMA__HPPA |
struct CMA__T_SEMAPHORE; |
# endif |
struct CMA__T_INT_CV; |
struct CMA__T_INT_MUTEX; |
struct CMA__T_INT_TCB; |
#endif |
|
typedef cma_t_address *cma__t_context_list; |
|
typedef struct CMA__T_TCB_PAD { |
/* |
* Adjust to align the tcb prolog at byte 32. |
* 12 bytes are required as object header is currently |
* 20 bytes long. |
*/ |
cma_t_integer pad1; /* pad bytes */ |
cma_t_integer pad2; /* pad bytes */ |
cma_t_integer pad3; /* pad bytes */ |
} cma__t_tcb_pad; |
|
#if (_CMA_OS_ == _CMA__UNIX) && !_CMA_THREAD_SYNC_IO_ |
typedef struct CMA__T_TCB_SELECT { |
cma__t_queue queue; |
#if (_CMA_UNIX_TYPE != _CMA__SVR4) |
cma__t_file_mask *rfds; |
cma__t_file_mask *wfds; |
cma__t_file_mask *efds; |
#else |
cma__t_poll_info poll_info; |
#endif /* (_CMA_UNIX_TYPE != _CMA__SVR4) */ |
cma_t_integer nfound; |
} cma__t_tcb_select; |
#endif |
|
typedef struct CMA__T_TCB_TIME { |
cma__t_queue queue; /* must be first entry! */ |
cma_t_integer mode; |
struct CMA__T_SEMAPHORE *semaphore; /* used for timed semaphores */ |
cma_t_date_time wakeup_time; |
cma_t_integer quanta_remaining; |
} cma__t_tcb_time; |
|
typedef enum CMA__T_DEBEVT { |
cma__c_debevt_activating = 1, /* First transition to running */ |
cma__c_debevt_running = 2, /* Any transition to running */ |
cma__c_debevt_preempting = 3, /* Preemted (replaced) another thread */ |
cma__c_debevt_blocking = 4, /* Any transition to blocked */ |
cma__c_debevt_terminating = 5, /* Final state transition */ |
cma__c_debevt_term_alert = 6, /* Terminated due to alert/cancel */ |
cma__c_debevt_term_exc = 7, /* Terminated due to exception */ |
cma__c_debevt_exc_handled = 8 /* Exception is being handled */ |
} cma__t_debevt; |
|
#define cma__c_debevt__first ((cma_t_integer)cma__c_debevt_activating) |
#define cma__c_debevt__last ((cma_t_integer)cma__c_debevt_exc_handled) |
#define cma__c_debevt__dim (cma__c_debevt__last + 1) |
|
/* |
* Type defining thread substate, which is used by the debugger. |
* If the state is blocked, substate indicates WHY the thread is blocked. |
*/ |
typedef enum CMA__T_SUBSTATE { |
cma__c_substa_normal = 0, |
cma__c_substa_mutex = 1, |
cma__c_substa_cv = 2, |
cma__c_substa_timed_cv = 3, |
cma__c_substa_term_alt = 4, |
cma__c_substa_term_exc = 5, |
cma__c_substa_delay =6, |
cma__c_substa_not_yet_run = 7 |
} cma__t_substate; |
#define cma__c_substa__first ((cma_t_integer)cma__c_substa_normal) |
#define cma__c_substa__last ((cma_t_integer)cma__c_substa_not_yet_run) |
#define cma__c_substa__dim (cma__c_substa__last + 1) |
|
|
/* |
* Per-thread state for the debugger |
*/ |
typedef struct CMA__T_TCB_DEBUG { |
cma_t_boolean on_hold; /* Thread was put on hold by debugger */ |
cma_t_boolean activated; /* Activation event was reported */ |
cma_t_boolean did_preempt; /* Thread preempted prior one */ |
cma_t_address start_pc; /* Start routine address */ |
cma_t_address object_addr; /* Addr of thread object */ |
cma__t_substate substate; /* Reason blocked, terminated, etc.*/ |
cma_t_boolean notify_debugger;/* Notify debugger thread is running */ |
cma_t_address SPARE2; /* SPARE */ |
cma_t_address SPARE3; /* SPARE */ |
struct CMA__T_INT_TCB |
*preempted_tcb; /* TCB of thread that got preempted */ |
cma_t_boolean flags[cma__c_debevt__dim]; |
/* Events enabled for this thread */ |
} cma__t_tcb_debug; |
|
typedef struct CMA__T_TCB_SCHED { |
cma_t_integer adj_time; /* Abs. time in ticks of last prio adj */ |
cma_t_integer tot_time; /* Weighted ave in ticks (scaled) */ |
cma_t_integer time_stamp; /* Abs. time in ticks of last update */ |
cma_t_integer cpu_time; /* Weighted average in ticks */ |
cma_t_integer cpu_ticks; /* # of ticks while comp. (scaled) */ |
cma_t_integer q_num; /* Number of last ready queue on */ |
cma_t_priority priority; /* Thread priority */ |
cma_t_sched_policy policy; /* Scheduling policy of thread */ |
cma_t_boolean rtb; /* "Run 'Till Block" scheduling */ |
cma_t_boolean spp; /* "Strict Priority Preemption" sched */ |
cma_t_boolean fixed_prio; /* Fixed priority */ |
cma__t_sched_class class; /* Scheduling class */ |
struct CMA__T_VP *processor; /* Current processor (if running) */ |
} cma__t_tcb_sched; |
|
typedef struct CMA__T_INT_ALERT { |
cma_t_boolean pending : 1; /* alert_pending bit */ |
cma_t_boolean g_enable : 1; /* general delivery state */ |
cma_t_boolean a_enable : 1; /* asynchronous delivery state */ |
cma_t_integer spare : 29; /* Pad to longword */ |
cma_t_natural count; /* Alert scope nesting count */ |
} cma__t_int_alert; |
|
typedef enum CMA__T_STATE { |
cma__c_state_running = 0, /* For consistency with initial TCB */ |
cma__c_state_ready = 1, |
cma__c_state_blocked = 2, |
cma__c_state_terminated = 3 |
} cma__t_state; |
#define cma__c_state__first ((cma_t_integer)cma__c_state_running) |
#define cma__c_state__last ((cma_t_integer)cma__c_state_terminated) |
#define cma__c_state__dim (cma__c_state__last + 1) |
|
typedef enum CMA__T_THKIND { |
cma__c_thkind_initial = 0, /* Initial thread */ |
cma__c_thkind_normal = 1, /* Normal thread */ |
cma__c_thkind_null = 2 /* A null thread */ |
} cma__t_thkind; |
#define cma__c_thkind__first ((cma_t_integer)cma__c_thkind_initial) |
#define cma__c_thkind__last ((cma_t_integer)cma__c_thkind_null) |
#define cma__c_thkind__dim (cma__c_thkind__last + 1) |
|
typedef enum CMA__T_SYSCALL_STATE { |
cma__c_syscall_ok = 1, /* syscall was not interrupted */ |
cma__c_syscall_intintrpt = 1, /* syscall was interrupted by VTALRM */ |
cma__c_syscall_extintrpt = 2 /* syscall was interrupted by external signal */ |
} cma__t_syscall_state; |
|
|
typedef struct CMA__T_INT_TCB { |
/* |
* Fixed part of TCB. |
* Modifications to the following three fields must be coordinated. |
* The object header must always be first, and the prolog must always |
* remain at the same offset (32) for all time. Thus the object header |
* must never grow beyond a maximum of 32 bytes. |
*/ |
cma__t_object header; /* Common object header */ |
cma__t_tcb_pad pad1; /* Pad required to align prolog */ |
cma_t_tcb_prolog prolog; /* Standard prolog for tasks, threads */ |
|
/* |
* Floating part of TCB (fields here on are free to be moved and resized). |
*/ |
cma__t_queue threads; /* List of all known threads */ |
cma__t_int_attr *attributes; /* Backpointer to attr obj */ |
cma__t_state state; /* Current state of thread */ |
cma__t_thkind kind; /* Which kind of thread */ |
struct CMA__T_INT_MUTEX |
*mutex; /* Mutex to control TCB access */ |
struct CMA__T_INT_CV |
*term_cv; /* CV for join */ |
struct CMA__T_INT_MUTEX |
*tswait_mutex; /* Mutex for thread-synchronous waits */ |
struct CMA__T_INT_CV |
*tswait_cv; /* CV for thread-synchronous waits */ |
cma_t_start_routine start_code; /* Address of start routine */ |
cma_t_address start_arg; /* Argument to pass to start_code */ |
cma__t_queue stack; /* Queue header for stack descr. */ |
cma_t_natural context_count; /* Size of context array */ |
cma__t_context_list contexts; /* Context value array pointer */ |
cma_t_exit_status exit_status; /* Exit status of thread */ |
cma_t_address return_value; /* Thread's return value */ |
cma__t_async_ctx async_ctx; /* Asynchronous context switch info */ |
cma__t_static_ctx static_ctx; /* Static context switch information */ |
cma_t_integer event_status; /* Status of semaphore operation */ |
cma__t_tcb_time timer; /* Time info for dispatcher */ |
cma__t_tcb_sched sched; /* Scheduler info */ |
cma__t_tcb_debug debug; /* Debugger info */ |
#if _CMA_OS_ == _CMA__UNIX |
# if !_CMA_THREAD_SYNC_IO_ |
cma__t_tcb_select select; /* Select info for timed selects */ |
# endif |
struct sigaction sigaction_data[NSIG]; |
#endif |
cma_t_natural syscall_state; /* set if one of the cma wrapped syscalls was interrupted. */ |
cma_t_boolean detached; /* Set if already detached */ |
cma_t_boolean terminated; /* Set if terminated */ |
cma_t_integer joiners; /* Count of joiners, for zombie frees */ |
cma__t_int_alert alert; /* Current alert state info */ |
struct CMA__T_INT_CV |
*wait_cv; /* CV thread is currently waiting on */ |
struct CMA__T_INT_MUTEX |
*wait_mutex; /* Mutex thread is waiting on */ |
struct EXC_CONTEXT_T |
*exc_stack; /* Top of exception stack */ |
#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX |
char ctx_stack[cma__c_ibmr2_ctx_stack_size]; |
#endif |
cma_t_integer thd_errno; /* Per-thread errno value */ |
#if _CMA_OS_ == _CMA__VMS |
cma_t_integer thd_vmserrno; /* Per-thread VMS errno value */ |
#endif |
} cma__t_int_tcb; |
|
#endif |
/cma_attr.h
0,0 → 1,341
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for attributes object |
*/ |
|
#ifndef CMA_ATTR |
#define CMA_ATTR |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma_defs.h> |
#include <cma_queue.h> |
#ifdef __hpux |
# include <sys/param.h> |
#endif |
#if _CMA_UNIX_TYPE == _CMA__SVR4 |
#include <sys/unistd.h> |
#endif |
/* |
* CONSTANTS AND MACROS |
*/ |
|
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_get_priority - Performs the work of cma_attr_get_priority |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ - Attribute object to get from |
* cma_t_priority *_setting_ - Current setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* priority |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#define cma__int_attr_get_priority(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
(_int_att_) = cma__validate_default_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
(*(_setting_)) = (_int_att_)->priority; \ |
cma__int_unlock ((_int_att_)->mutex); \ |
} |
|
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_get_sched - Performs work of cma_attr_get_sched |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ _ Attributes object used |
* cma_t_sched_policy *_setting_ - Current setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* scheduling policy |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#define cma__int_attr_get_sched(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
(_int_att_) = cma__validate_default_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
(*(_setting_)) = (_int_att_)->policy; \ |
cma__int_unlock ((_int_att_)->mutex); \ |
} |
|
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_get_inherit_sched - Performs work of |
* cma_attr_get_inherit_sched |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ - Attributes object to use |
* cma_t_sched_inherit *_setting_ - Current setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* Inheritable scheduling policy |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#define cma__int_attr_get_inherit_sched(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
(_int_att_) = cma__validate_default_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
(*(_setting_)) \ |
= ((_int_att_)->inherit_sched ? cma_c_sched_inherit : cma_c_sched_use_default); \ |
cma__int_unlock ((_int_att_)->mutex); \ |
} |
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_set_stacksize - Performs work for cma_attr_set_stacksize |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ - Attributes object to use |
* cma_t_natural _setting_ - Setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* none |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* Change attribute objects stack size setting |
*/ |
#define cma__int_attr_set_stacksize(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
if ((_setting_) <= 0) \ |
cma__error (cma_s_badparam); \ |
_int_att_ = cma__validate_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
_int_att_->stack_size = cma__roundup_chunksize(_setting_); \ |
cma__free_cache (_int_att_, cma__c_obj_tcb); \ |
_int_att_->cache[cma__c_obj_tcb].revision++; \ |
_int_att_->cache[cma__c_obj_stack].revision++; \ |
cma__int_unlock (_int_att_->mutex); \ |
} |
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_get_stacksize - Performs work of cma_attr_get_stacksize |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ - Attributes object to use |
* cma_t_natural *_setting_ - Current setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* Attribute objects stack size setting |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#define cma__int_attr_get_stacksize(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
(_int_att_) = cma__validate_default_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
(*(_setting_)) = (_int_att_)->stack_size; \ |
cma__int_unlock ((_int_att_)->mutex); \ |
} |
|
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_set_guardsize - Performs work for cma_attr_set_guardsize |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ - Attributes object to use |
* cma_t_natural _setting_ - Setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* none |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* Change attribute objects guard size setting |
*/ |
#define cma__int_attr_set_guardsize(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
_int_att_ = cma__validate_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
_int_att_->guard_size = cma__roundup_chunksize(_setting_); \ |
cma__free_cache (_int_att_, cma__c_obj_tcb); \ |
_int_att_->cache[cma__c_obj_tcb].revision++; \ |
_int_att_->cache[cma__c_obj_stack].revision++; \ |
cma__int_unlock (_int_att_->mutex); \ |
} |
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_attr_get_guardsize - Performs work of cma_attr_get_guardsize |
* |
* FORMAL PARAMETERS: |
* |
* cma_t_attr *_att_ - Attributes object to use |
* cma_t_natural *_setting_ - Current setting |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* Attribute objects guard size setting |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#define cma__int_attr_get_guardsize(_att_,_setting_) { \ |
cma__t_int_attr *_int_att_; \ |
(_int_att_) = cma__validate_default_attr (_att_); \ |
cma__int_lock ((_int_att_)->mutex); \ |
(*(_setting_)) = (_int_att_)->guard_size; \ |
cma__int_unlock ((_int_att_)->mutex); \ |
} |
|
/* |
* TYPEDEFS |
*/ |
#ifndef __STDC__ |
struct CMA__T_INT_MUTEX; /* Avoid circular dependency */ |
#endif |
|
typedef struct CMA__T_CACHE { |
cma_t_natural revision; /* Revisions */ |
cma_t_natural count; |
cma__t_queue queue; /* Cache headers */ |
} cma__t_cache; |
|
typedef struct CMA__T_INT_ATTR { |
cma__t_object header; /* Common header */ |
struct CMA__T_INT_ATTR *attributes; /* Point to controlling attr */ |
struct CMA__T_INT_MUTEX *mutex; /* Serialize access to object */ |
cma_t_priority priority; /* Priority of new thread */ |
cma_t_sched_policy policy; /* Sched policy of thread */ |
cma_t_boolean inherit_sched; /* Is scheduling inherited? */ |
cma_t_natural stack_size; /* Size of stack (bytes) */ |
cma_t_natural guard_size; /* Size of guard (bytes) */ |
cma_t_mutex_kind mutex_kind; /* Mutex kind */ |
cma__t_cache cache[cma__c_obj_num]; /* Cache information */ |
cma_t_boolean delete_pending; /* attr. obj. is deleted */ |
cma_t_natural refcnt; /* Number of objects using attr. obj */ |
} cma__t_int_attr; |
|
/* |
* GLOBAL DATA |
*/ |
|
extern cma__t_int_attr cma__g_def_attr; |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern void cma__destroy_attributes (cma__t_int_attr *); |
|
extern void cma__free_attributes (cma__t_int_attr *); |
|
extern void cma__free_cache (cma__t_int_attr *,cma_t_natural ); |
|
extern cma__t_int_attr *cma__get_attributes (cma__t_int_attr *); |
|
extern void cma__init_attr (void); |
|
extern void cma__reinit_attr (cma_t_integer); |
|
#endif |
/cma_list.h
0,0 → 1,84
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for generic list functions operating on singly linked |
* null-terminated lists. Items may not be REMOVED from the list! The |
* intent is that the list can be traversed (for read-only operations) |
* without locking, since insertion is "safe" (though not truely |
* atomic). THIS ASSUMES THAT THE HARDWARE MAKES WRITES VISIBLE TO READS |
* IN THE ORDER IN WHICH THEY OCCURRED! WITHOUT SUCH READ/WRITE |
* ORDERING, IT MAY BE NECESSARY TO INSERT "BARRIERS" TO PRODUCE THE |
* REQUIRED VISIBILITY! |
*/ |
|
#ifndef CMA_LIST |
#define CMA_LIST |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#define cma__c_null_list ((cma__t_list *)cma_c_null_ptr) |
|
/* |
* Test whether a list is empty. Return cma_c_true if so, else |
* cma_c_false. |
*/ |
#define cma__list_empty(head) ((head)->link == cma__c_null_list) |
|
/* |
* Initialize a queue header to empty. |
*/ |
#define cma__list_init(head) (void)((head)->link = cma__c_null_list) |
|
/* |
* Insert an element in a list following the specified item (or at the |
* beginning of the list if "list" is the list head). NOTE: insertion |
* operations should be interlocked by the caller! |
*/ |
#define cma__list_insert(element,list) (void)( \ |
(element)->link = (list)->link, \ |
(list)->link = (element)) |
|
/* |
* Return the next item in a list (or the first, if the address is of the |
* list header) |
*/ |
#define cma__list_next(element) ((element)->link) |
|
/* |
* TYPEDEFS |
*/ |
|
typedef struct CMA__T_LIST { |
struct CMA__T_LIST *link; /* Forward link */ |
} cma__t_list; |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
#endif |
/cma_errors.h
0,0 → 1,55
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* This module is the interface between CMA services and |
* the platform-specific error reporting mechanism. |
*/ |
|
#ifndef CMA_ERRORS |
#define CMA_ERRORS |
|
/* |
* INCLUDE FILES |
*/ |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
/* |
* TYPEDEFS |
*/ |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
/* |
* The cma__bugcheck function will print information to stderr (or sys$error |
* on VMS), and more extensive information to the file cma_dump.log in the |
* current working directory. |
*/ |
extern void cma__bugcheck (char *,...); |
|
extern void cma__error (int); |
|
extern void cma__unimplemented (void); |
|
#endif |
/cma_util.h
0,0 → 1,125
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for CMA internal UTIL operations |
*/ |
|
#ifndef CMA_UTIL |
#define CMA_UTIL |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma.h> |
#include <cma_attr.h> |
#include <cma_defs.h> |
|
#if _CMA_OS_ == _CMA__VMS |
# include <cma_rms.h> |
#endif |
|
#if _CMA_VENDOR_ == _CMA__SUN |
# include <sys/time.h> |
#else |
# include <time.h> |
#endif |
|
#if _CMA_OS_ == _CMA__UNIX |
# include <stdio.h> |
#endif |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#define cma__c_buffer_size 256 /* Size of output buffer */ |
|
/* |
* TYPEDEFS |
*/ |
|
/* |
* Alternate eol routine |
*/ |
typedef void (*cma__t_eol_routine) (char *); |
|
#if _CMA_OS_ == _CMA__VMS |
typedef struct CMA__T_VMSFILE { |
struct RAB rab; |
struct FAB fab; |
} cma__t_vmsfile, *cma__t_file; |
#elif ( _CMA_UNIX_TYPE == _CMA__SVR4 ) |
typedef int cma__t_file; |
#else |
typedef FILE *cma__t_file; |
#endif |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern void cma__abort (void); |
|
extern cma_t_integer cma__atol (char *); |
|
extern cma_t_integer cma__atoi (char *); |
|
extern char * cma__getenv (char *,char *,int); |
|
extern int cma__gettimespec (struct timespec *); |
|
extern cma__t_file cma__int_fopen (char *,char *); |
|
#ifndef NDEBUG |
extern void cma__init_trace (char *_env); |
#endif |
|
extern char * cma__memcpy (char *,char *,cma_t_integer); |
|
#ifndef cma__memset |
extern char * cma__memset (char *,cma_t_integer,cma_t_integer); |
#endif |
|
extern void cma__putformat (char *,char *,...); |
|
extern void cma__putstring (char *,char *); |
|
extern void cma__putint (char *,cma_t_integer); |
|
extern void cma__putint_5 (char *,cma_t_integer); |
|
extern void cma__putint_10 (char *,cma_t_integer); |
|
extern void cma__puthex (char *,cma_t_integer); |
|
extern void cma__puthex_8 (char *,cma_t_integer); |
|
extern void cma__puteol (char *); |
|
extern void cma__set_eol_routine (cma__t_eol_routine,cma__t_eol_routine *); |
|
extern cma_t_integer cma__strlen (char *); |
|
extern int cma__strncmp (char *,char *,cma_t_integer); |
|
extern char *cma__gets (char *,char *); |
|
#endif |
/cma_stack_int.h
0,0 → 1,136
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for stack management (internal to cma_stack.c, but |
* separate for convenience, and unit testing). |
*/ |
|
#ifndef CMA_STACK_INT |
#define CMA_STACK_INT |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma.h> |
#include <cma_queue.h> |
#include <cma_list.h> |
#include <cma_tcb_defs.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#define cma___c_first_free_chunk 0 |
#define cma___c_min_count 2 /* Smallest number of chunks to leave */ |
#define cma___c_end (-1) /* End of free list (flag) */ |
#define cma__c_yellow_size 0 |
|
/* |
* Cluster types |
*/ |
#define cma___c_cluster 0 /* Default cluster */ |
#define cma___c_bigstack 1 /* Looks like a cluster, but it's a stack */ |
|
|
#define cma___c_null_cluster (cma___t_cluster *)cma_c_null_ptr |
|
|
/* |
* TYPEDEFS |
*/ |
|
#ifndef __STDC__ |
struct CMA__T_INT_STACK; |
#endif |
|
typedef cma_t_natural cma___t_index; /* Type for chunk index */ |
|
typedef struct CMA___T_CLU_DESC { |
cma__t_list list; /* Queue element for cluster list */ |
cma_t_integer type; /* Type of cluster */ |
cma_t_address stacks; |
cma_t_address limit; |
} cma___t_clu_desc; |
|
typedef union CMA___T_MAP_ENTRY { |
struct { |
cma__t_int_tcb *tcb; /* TCB associated with stack chunk */ |
struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack chunk */ |
} mapped; |
struct { |
cma___t_index size; /* Number of chunks in block */ |
cma___t_index next; /* Next free block */ |
} free; |
} cma___t_map_entry; |
|
/* |
* NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack |
* begin with the cma___t_clu_desc structure, as there is some code in the |
* stack manager that relies on being able to treat both as equivalent! |
*/ |
typedef struct CMA___T_CLUSTER { |
cma___t_clu_desc desc; /* Describe this cluster */ |
cma___t_map_entry map[cma__c_chunk_count]; /* thread map */ |
cma___t_index free; /* First free chunk index */ |
} cma___t_cluster; |
|
/* |
* NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack |
* begin with the cma___t_clu_desc structure, as there is some code in the |
* stack manager that relies on being able to treat both as equivalent! |
*/ |
typedef struct CMA___T_BIGSTACK { |
cma___t_clu_desc desc; /* Describe this cluster */ |
cma__t_int_tcb *tcb; /* TCB associated with stack */ |
struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack */ |
cma_t_natural size; /* Size of big stack */ |
cma_t_boolean in_use; /* Set if allocated */ |
} cma___t_bigstack; |
|
#if _CMA_PROTECT_MEMORY_ |
typedef struct CMA___T_INT_HOLE { |
cma__t_queue link; /* Link holes together */ |
cma_t_boolean protected; /* Set when pages are protected */ |
cma_t_address first; /* First protected byte */ |
cma_t_address last; /* Last protected byte */ |
} cma___t_int_hole; |
#endif |
|
typedef struct CMA__T_INT_STACK { |
cma__t_object header; /* Common header (sequence, type info */ |
cma__t_int_attr *attributes; /* Backpointer to attr obj */ |
cma___t_cluster *cluster; /* Stack's cluster */ |
cma_t_address stack_base; /* base address of stack */ |
cma_t_address yellow_zone; /* first address of yellow zone */ |
cma_t_address last_guard; /* last address of guard pages */ |
cma_t_natural first_chunk; /* First chunk allocated */ |
cma_t_natural chunk_count; /* Count of chunks allocated */ |
cma__t_int_tcb *tcb; /* TCB backpointer */ |
#if _CMA_PROTECT_MEMORY_ |
cma___t_int_hole hole; /* Description of hole */ |
#endif |
} cma__t_int_stack; |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
#endif |
/cma_semaphore_defs.h
0,0 → 1,46
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for semaphore structure definition. |
*/ |
#ifndef CMA_SEMAPHORE_DEFS |
#define CMA_SEMAPHORE_DEFS |
|
/* |
* INCLUDE FILES |
*/ |
#include <cma.h> |
#include <cma_queue.h> |
#include <cma_defs.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#define cma__c_semaphore_timeout 1 |
#define cma__c_semaphore_event 0 |
#define cma__c_select_timeout 2 |
|
/* |
* TYPEDEFS |
*/ |
|
typedef struct CMA__T_SEMAPHORE { |
cma__t_queue queue; |
cma__t_atomic_bit nopending; |
} cma__t_semaphore; |
|
#endif |
/cma_debug_client.h
0,0 → 1,195
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file providing access to CMA clients that implement |
* language run-times to the CMA debugger capabilities. |
* |
* NOTE: the clients that are able to use this interface is |
* very limited because clients needing task debugging must have |
* support in the system debugger as well as here (at present). |
* The following are the only legitimate clients of this interface: |
* ADA runtime, C++ tasking library, and CMA. |
* |
*FIX-ME* We shall endeavor to extend these capabilities so that the |
* all-platform CMA debugger CMA_DEBUG and any client can layer |
* on thread debugging. But that is still an open design problem. |
* The design here does not preclude that extension (for example, |
* the identity of the debug-client is indicated in an "open" |
* manner by using the CMA context key as the identifier. |
*/ |
|
#ifndef CMA_DEBUG_CLIENT |
#define CMA_DEBUG_CLIENT |
|
/* |
* INCLUDE FILES |
*/ |
#include <cma.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
/* |
* TYPEDEFS |
*/ |
|
/* |
* Type describing constants for a valid TCB sentinel. |
* Exactly one value is valid, but we provide a symbolic name for |
* at least one invalid sentinel as a convenience. |
*/ |
typedef enum CMA_T_TCB_SENTINEL { |
cma_c_tcb_sentinel_nogood = 0, /* Invalid sentinel constant */ |
cma_c_tcb_sentinel = 0x0ACEFACE /* Valid TCB sentinel */ |
} cma_t_tcb_sentinel; |
|
/* |
* Type describing pad fields needed to align the "standard prolog" |
* to the right byte at the front of each TCB. These fields are |
* free to be put to any use by the client. |
* |
* This is 32 bytes long and is fixed at this size for all clients |
* and CMA, for all time. |
*/ |
typedef struct CMA_T_TCB_PRIVATE { |
cma_t_integer pad1; |
cma_t_integer pad2; |
cma_t_integer pad3; |
cma_t_integer pad4; |
cma_t_integer pad5; |
cma_t_integer pad6; |
cma_t_integer pad7; |
cma_t_integer pad8; |
} cma_t_tcb_private; |
|
/* |
* Type describing the "standard prolog" that clients should use |
* within their task control blocks. We assume that the client will |
* store their "task control block" as a per-thread context under |
* the context key specified here. |
*/ |
typedef struct CMA_T_TCB_PROLOG { |
cma_t_tcb_sentinel sentinel; /* Validity sentinel */ |
cma_t_thread client_thread; /* Thread corresonding to task */ |
cma_t_key client_key; /* Context key this is stored under */ |
cma_t_address reserved1; /* Must be zero, reserved to CMA */ |
} cma_t_tcb_prolog; |
|
/* |
* Type defining the layout of all TCBs and TASKS. This format |
* ensures that tasks will be self-identifying to the debugger. |
* this layout must never change as the CMA DEBUG Clients cannot |
* be changed after CMA ships. |
*/ |
typedef struct CMA_T_TCB_HEADER { |
cma_t_tcb_private IGNORED; /* TCB fields private to the client */ |
cma_t_tcb_prolog prolog; /* The standard prolog goes here */ |
} cma_t_tcb_header; |
|
|
/* |
* Type describing the kinds of information that a CMA debug |
* client can GET about a thread. |
*/ |
typedef enum CMA_T_DEBUG_GET { |
/* |
* All of the following items use a buffer whose size is |
* four bytes. (That is four must be passed as the buffer_size |
* parameter to cma_debug_get.) |
*/ |
cma_c_debget_guardsize = 1, /* Current guard size (bytes) */ |
cma_c_debget_is_held = 2, /* Is it on hold? */ |
cma_c_debget_is_initial = 3, /* Is it the initial thread? */ |
cma_c_debget_number = 4, /* Thread's number */ |
cma_c_debget_stack_ptr = 5, /* Current stack pointer */ |
cma_c_debget_stack_base = 6, /* Stack base address */ |
cma_c_debget_stack_top = 7, /* Stack top address */ |
cma_c_debget_sched_state = 8, /* Scheduler state |
* 0 - run |
* 1 - ready |
* 2 - blocked |
* 3 - terminated |
*/ |
cma_c_debget_reserve_size = 9, /* Size of stack reserve (bytes) */ |
cma_c_debget_base_prio = 10, /* Base priority */ |
cma_c_debget_priority = 11, /* Current priority */ |
cma_c_debget_regs = 12, /* Register set (and proc. state) */ |
cma_c_debget_alt_pending = 13, /* Alert is pending */ |
cma_c_debget_alt_a_enable = 14, /* Asynch alert delivery enabled */ |
cma_c_debget_alt_g_enable = 15, /* General alert delivery enabled */ |
cma_c_debget_substate = 16, /* Substate (or wait state) */ |
cma_c_debget_object_addr = 17, /* Address of thread object */ |
cma_c_debget_thkind = 18, /* Kind of thread */ |
cma_c_debget_detached = 19, /* Thread is detached */ |
cma_c_debget_tcb_size = 20, /* TCB size */ |
cma_c_debget_start_pc = 21, /* Start address */ |
cma_c_debget_next_pc = 22, /* Next instruction */ |
cma_c_debget_policy = 23, /* Sched policy */ |
cma_c_debget_stack_yellow = 24, /* Addr of start of guard area */ |
cma_c_debget_stack_default = 25 /* True if on default stack */ |
|
} cma_t_debug_get; |
|
/* |
* Type describing the kinds of information that a CMA debug |
* client can SET (or change) about a thread using cma_debug_set. |
*/ |
typedef enum CMA_T_DEBUG_SET { |
/* |
* All of the following items use a buffer whose size is |
* four bytes. (That is four must be passed as the buffer_size |
* parameter to cma_debug_set.) |
*/ |
cma_c_debset_priority = 1, /* Set the priority */ |
cma_c_debset_policy = 2, /* Set the sched policy */ |
cma_c_debset_hold = 3, /* Put thread on hold */ |
cma_c_debset_regs = 4 /* Set the regs and proc. state */ |
|
} cma_t_debug_set; |
|
|
/* |
* GLOBAL DATA |
* |
* none |
*/ |
|
/* |
* EXTERNAL INTERFACES |
*/ |
|
/* |
* Routine to register with the CMA debug dispatcher. |
*/ |
extern void cma_debug_register (cma_t_address,cma_t_key,cma_t_integer,cma_t_boolean); |
|
/* |
* Routine to get get thread state needed by the CMA debug client. |
*/ |
extern void cma_debug_get (cma_t_thread *,cma_t_debug_get,cma_t_address,cma_t_integer); |
|
/* |
* Get thread context given an sp and a key |
*/ |
extern void cma_debug_get_sp_context (cma_t_address,cma_t_key,cma_t_address *); |
|
/* |
* Routine to set thread state as needed by the CMA debug client. |
*/ |
extern void cma_debug_set (cma_t_thread *,cma_t_debug_set,cma_t_address,cma_t_integer); |
|
#endif |
/cma_sched.h
0,0 → 1,279
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for priority scheduling |
*/ |
|
|
#ifndef CMA_SCHED |
#define CMA_SCHED |
|
/* |
* INCLUDE FILES |
*/ |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
/* |
* Scaling factor for integer priority calculations |
*/ |
#define cma__c_prio_scale 8 |
|
#if _CMA_VENDOR_ == _CMA__APOLLO |
/* |
* FIX-ME: Apollo cc 6.8 blows contant folded "<<" and ">>" |
*/ |
# define cma__scale_up(exp) ((exp) * 256) |
# define cma__scale_dn(exp) ((exp) / 256) |
#else |
# define cma__scale_up(exp) ((exp) << cma__c_prio_scale) |
# define cma__scale_dn(exp) ((exp) >> cma__c_prio_scale) |
#endif |
|
|
/* |
* Min. num. of ticks between self-adjustments for priority adjusting policies. |
*/ |
#define cma__c_prio_interval 10 |
|
|
/* |
* Number of queues in each class of queues |
*/ |
#define cma__c_prio_n_id 1 /* Very-low-priority class threads */ |
#define cma__c_prio_n_bg 8 /* Background class threads */ |
#define cma__c_prio_n_0 1 /* Very low priority throughput quartile */ |
#define cma__c_prio_n_1 2 /* Low priority throughput quartile */ |
#define cma__c_prio_n_2 3 /* Medium priority throughput quartile */ |
#define cma__c_prio_n_3 4 /* High priority throughput quartile */ |
#define cma__c_prio_n_rt 1 /* Real Time priority queues */ |
|
/* |
* Number of queues to skip (offset) to get to the queues in this section of LA |
*/ |
#define cma__c_prio_o_id 0 |
#define cma__c_prio_o_bg cma__c_prio_o_id + cma__c_prio_n_id |
#define cma__c_prio_o_0 cma__c_prio_o_bg + cma__c_prio_n_bg |
#define cma__c_prio_o_1 cma__c_prio_o_0 + cma__c_prio_n_0 |
#define cma__c_prio_o_2 cma__c_prio_o_1 + cma__c_prio_n_1 |
#define cma__c_prio_o_3 cma__c_prio_o_2 + cma__c_prio_n_2 |
#define cma__c_prio_o_rt cma__c_prio_o_3 + cma__c_prio_n_3 |
|
/* |
* Ada_low: These threads are queued in the background queues, thus there |
* must be enough queues to allow one queue for each Ada priority below the |
* Ada default. |
*/ |
#define cma__c_prio_o_al cma__c_prio_o_bg |
|
/* |
* Total number of ready queues, for declaration purposes |
*/ |
#define cma__c_prio_n_tot \ |
cma__c_prio_n_id + cma__c_prio_n_bg + cma__c_prio_n_rt \ |
+ cma__c_prio_n_0 + cma__c_prio_n_1 + cma__c_prio_n_2 + cma__c_prio_n_3 |
|
/* |
* Formulae for determining a thread's priority. Variable priorities (such |
* as foreground and background) are scaled values. |
*/ |
#define cma__sched_priority(tcb) \ |
((tcb)->sched.class == cma__c_class_fore ? cma__sched_prio_fore (tcb) \ |
:((tcb)->sched.class == cma__c_class_back ? cma__sched_prio_back (tcb) \ |
:((tcb)->sched.class == cma__c_class_rt ? cma__sched_prio_rt (tcb) \ |
:((tcb)->sched.class == cma__c_class_idle ? cma__sched_prio_idle (tcb) \ |
:(cma__bugcheck ("cma__sched_priority: unrecognized class"), 0) )))) |
|
#define cma__sched_prio_fore(tcb) cma__sched_prio_fore_var (tcb) |
#define cma__sched_prio_back(tcb) ((tcb)->sched.fixed_prio \ |
? cma__sched_prio_back_fix (tcb) : cma__sched_prio_back_var (tcb) ) |
#define cma__sched_prio_rt(tcb) ((tcb)->sched.priority) |
#define cma__sched_prio_idle(tcb) ((tcb)->sched.priority) |
|
#define cma__sched_prio_back_fix(tcb) \ |
(cma__g_prio_bg_min + (cma__g_prio_bg_max - cma__g_prio_bg_min) \ |
* ((tcb)->sched.priority + cma__c_prio_o_al - cma__c_prio_o_bg) \ |
/ cma__c_prio_n_bg) |
|
/* |
* FIX-ME: Enable after modeling (if we like it) |
*/ |
#if 1 |
# define cma__sched_prio_fore_var(tcb) \ |
((cma__g_prio_fg_max + cma__g_prio_fg_min)/2) |
# define cma__sched_prio_back_var(tcb) \ |
((cma__g_prio_bg_max + cma__g_prio_bg_min)/2) |
#else |
# define cma__sched_prio_back_var(tcb) cma__sched_prio_fore_var (tcb) |
|
# if 1 |
/* |
* Re-scale, since the division removes the scale factor. |
* Scale and multiply before dividing to avoid loss of precision. |
*/ |
# define cma__sched_prio_fore_var(tcb) \ |
((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time)) \ |
/ (tcb)->sched.cpu_time) |
# else |
/* |
* Re-scale, since the division removes the scale factor. |
* Scale and multiply before dividing to avoid loss of precision. |
* Left shift the numerator to multiply by two. |
*/ |
# define cma__sched_prio_fore_var(tcb) \ |
(((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time) \ |
* (tcb)->sched.priority * cma__g_init_frac_sum) << 1) \ |
/ ((tcb)->sched.cpu_time * (tcb)->sched.priority * cma__g_init_frac_sum \ |
+ (tcb)->sched.tot_time)) |
# endif |
#endif |
|
/* |
* Update weighted-averaged, scaled tick counters |
*/ |
#define cma__sched_update_time(ave, new) \ |
(ave) = (ave) - ((cma__scale_dn((ave)) - (new)) << (cma__c_prio_scale - 4)) |
|
#define cma__sched_parameterize(tcb, policy) { \ |
switch (policy) { \ |
case cma_c_sched_fifo : { \ |
(tcb)->sched.rtb = cma_c_true; \ |
(tcb)->sched.spp = cma_c_true; \ |
(tcb)->sched.fixed_prio = cma_c_true; \ |
(tcb)->sched.class = cma__c_class_rt; \ |
break; \ |
} \ |
case cma_c_sched_rr : { \ |
(tcb)->sched.rtb = cma_c_false; \ |
(tcb)->sched.spp = cma_c_true; \ |
(tcb)->sched.fixed_prio = cma_c_true; \ |
(tcb)->sched.class = cma__c_class_rt; \ |
break; \ |
} \ |
case cma_c_sched_throughput : { \ |
(tcb)->sched.rtb = cma_c_false; \ |
(tcb)->sched.spp = cma_c_false; \ |
(tcb)->sched.fixed_prio = cma_c_false; \ |
(tcb)->sched.class = cma__c_class_fore; \ |
break; \ |
} \ |
case cma_c_sched_background : { \ |
(tcb)->sched.rtb = cma_c_false; \ |
(tcb)->sched.spp = cma_c_false; \ |
(tcb)->sched.fixed_prio = cma_c_false; \ |
(tcb)->sched.class = cma__c_class_back; \ |
break; \ |
} \ |
case cma_c_sched_ada_low : { \ |
(tcb)->sched.rtb = cma_c_false; \ |
(tcb)->sched.spp = cma_c_true; \ |
(tcb)->sched.fixed_prio = cma_c_true; \ |
(tcb)->sched.class = cma__c_class_back; \ |
break; \ |
} \ |
case cma_c_sched_idle : { \ |
(tcb)->sched.rtb = cma_c_false; \ |
(tcb)->sched.spp = cma_c_false; \ |
(tcb)->sched.fixed_prio = cma_c_false; \ |
(tcb)->sched.class = cma__c_class_idle; \ |
break; \ |
} \ |
default : { \ |
cma__bugcheck ("cma__sched_parameterize: bad scheduling Policy"); \ |
break; \ |
} \ |
} \ |
} |
|
/* |
* TYPEDEFS |
*/ |
|
/* |
* Scheduling classes |
*/ |
typedef enum CMA__T_SCHED_CLASS { |
cma__c_class_rt, |
cma__c_class_fore, |
cma__c_class_back, |
cma__c_class_idle |
} cma__t_sched_class; |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* Minimuma and maximum prioirities, for foreground and background threads, |
* as of the last time the scheduler ran. (Scaled once.) |
*/ |
extern cma_t_integer cma__g_prio_fg_min; |
extern cma_t_integer cma__g_prio_fg_max; |
extern cma_t_integer cma__g_prio_bg_min; |
extern cma_t_integer cma__g_prio_bg_max; |
|
/* |
* The "m" values are the slopes of the four sections of linear approximation. |
* |
* cma__g_prio_m_I = 4*N(I)/cma__g_prio_range (Scaled once.) |
*/ |
extern cma_t_integer cma__g_prio_m_0, |
cma__g_prio_m_1, |
cma__g_prio_m_2, |
cma__g_prio_m_3; |
|
/* |
* The "b" values are the intercepts of the four sections of linear approx. |
* (Not scaled.) |
* |
* cma__g_prio_b_I = -N(I)*(I*prio_max + (4-I)*prio_min)/prio_range + prio_o_I |
*/ |
extern cma_t_integer cma__g_prio_b_0, |
cma__g_prio_b_1, |
cma__g_prio_b_2, |
cma__g_prio_b_3; |
|
/* |
* The "p" values are the end points of the four sections of linear approx. |
* |
* cma__g_prio_p_I = cma__g_prio_fg_min + (I/4)*cma__g_prio_range |
* |
* [cma__g_prio_p_0 is not defined since it is not used (also, it is the same |
* as cma__g_prio_fg_min).] (Scaled once.) |
*/ |
extern cma_t_integer cma__g_prio_p_1, |
cma__g_prio_p_2, |
cma__g_prio_p_3; |
|
/* |
* Points to the next queue for the dispatcher to check for ready threads. |
*/ |
extern cma_t_integer cma__g_next_ready_queue; |
|
/* |
* Points to the queues of virtual processors (for preempt victim search) |
*/ |
extern cma__t_queue cma__g_run_vps; |
extern cma__t_queue cma__g_susp_vps; |
extern cma_t_integer cma__g_vp_count; |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
#endif |
/README
0,0 → 1,8
This directory contains header files necessary to build a thread-aware GDB on |
systems based on OSF's CMA threads package. |
|
The latest version of these header files are available for free from: |
|
http://www.osf.org/mall/dce/SW-code |
|
Currently, the only port of GDB which supports CMA threads is HP/UX-10.10. |
/HP800/cma_thread_io.h
0,0 → 1,432
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* |
* Header file for thread synchrounous I/O |
*/ |
|
#ifndef CMA_THREAD_IO |
#define CMA_THREAD_IO |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma_config.h> |
#include <sys/file.h> |
#include <cma.h> |
#include <sys/types.h> |
#include <sys/time.h> |
#include <cma_init.h> |
#include <cma_errors.h> |
|
/* |
* CONSTANTS |
*/ |
|
|
|
/* |
* Maximum number of files (ie, max_fd+1) |
*/ |
#define cma__c_mx_file FD_SETSIZE |
|
/* |
* Number of bits per file descriptor bit mask (ie number of bytes * bits/byte) |
*/ |
#define cma__c_nbpm NFDBITS |
|
/* |
* TYPE DEFINITIONS |
*/ |
|
typedef enum CMA__T_IO_TYPE { |
cma__c_io_read = 0, |
cma__c_io_write = 1, |
cma__c_io_except = 2 |
} cma__t_io_type; |
#define cma__c_max_io_type 2 |
|
/* |
* From our local <sys/types.h>: |
* |
* typedef long fd_mask; |
* |
* typedef struct fd_set { |
* fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; |
* } fd_set; |
* |
*/ |
typedef fd_mask cma__t_mask; |
typedef fd_set cma__t_file_mask; |
|
|
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* Maximum number of files (ie, max_fd+1) as determined by getdtablesize(). |
*/ |
extern int cma__g_mx_file; |
|
/* |
* Number of submasks (ie "int" sized chunks) per file descriptor mask as |
* determined by getdtablesize(). |
*/ |
extern int cma__g_nspm; |
|
/* |
* MACROS |
*/ |
|
/* |
* Define a constant for the errno value which indicates that the requested |
* operation was not performed because it would block the process. |
*/ |
# define cma__is_blocking(s) \ |
((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \ |
(s == EALREADY) || (s == EDEADLK)) |
|
/* |
* It is necessary to issue an I/O function, before calling cma__io_wait() |
* in the following cases: |
* |
* * This file descriptor has been set non-blocking by CMA |
* * This file descriptor has been set non-blocking by the user. |
*/ |
|
#define cma__issue_io_call(fd) \ |
( (cma__g_file[fd]->non_blocking) || \ |
(cma__g_file[fd]->user_fl.user_non_blocking) ) |
|
|
#define cma__set_user_nonblocking(flags) \ |
|
/* |
* Determine if the file is open |
*/ |
/* |
* If the file gets closed while waiting for the mutex cma__g_file[rfd] |
* gets set to null. This results in a crash if NDEBUG is set to 0 |
* since cma__int_lock tries to dereference it to set the mutex ownership |
* after it gets the mutex. The following will still set the ownership |
* in cma__int_lock so we'll set it back to noone if cma__g_file is null |
* when we come back just in case it matters. It shouldn't since its no |
* longer in use but..... |
* Callers of this should recheck cma__g_file after the reservation to |
* make sure continueing makes sense. |
*/ |
#define cma__fd_reserve(rfd) \ |
{ \ |
cma__t_int_mutex *__mutex__; \ |
__mutex__ = cma__g_file[rfd]->mutex; \ |
cma__int_lock (__mutex__); \ |
if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \ |
cma__int_unlock(__mutex__); \ |
} |
|
|
/* |
* Unreserve a file descriptor |
*/ |
#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex) |
|
/* |
* AND together two select file descriptor masks |
*/ |
#define cma__fdm_and(target,a,b) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) \ |
(target)->fds_bits[__i__] = \ |
(a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \ |
} |
|
/* |
* Clear a bit in a select file descriptor mask |
* |
* FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_clr_bit(n,p) FD_CLR (n, p) |
|
/* |
* Copy the contents of one file descriptor mask into another. If the |
* destination operand is null, do nothing; if the source operand is null, |
* simply zero the destination. |
*/ |
#define cma__fdm_copy(src,dst,nfds) { \ |
if (dst) \ |
if (src) { \ |
cma__t_mask *__s__ = (cma__t_mask *)(src); \ |
cma__t_mask *__d__ = (cma__t_mask *)(dst); \ |
int __i__; \ |
for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \ |
*__d__++ = *__s__++; \ |
} \ |
else \ |
cma__fdm_zero (dst); \ |
} |
|
/* |
* To increment count for each bit set in fd - mask |
*/ |
#define cma__fdm_count_bits(map,count) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) { \ |
cma__t_mask __tm__; \ |
__tm__ = (map)->fds_bits[__i__]; \ |
while(__tm__) { \ |
(count)++; \ |
__tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \ |
} \ |
} \ |
} |
|
/* |
* Test if a bit is set in a select file descriptor mask |
* |
* FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_is_set(n,p) FD_ISSET (n, p) |
|
/* |
* OR together two select file descriptor masks |
*/ |
#define cma__fdm_or(target,a,b) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) \ |
(target)->fds_bits[__i__] = \ |
(a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \ |
} |
|
/* |
* Set a bit in a select file descriptor mask |
* |
* FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_set_bit(n,p) FD_SET (n, p) |
|
/* |
* Clear a select file descriptor mask. |
*/ |
#define cma__fdm_zero(n) \ |
cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask)) |
|
|
|
|
|
/* |
* CMA "thread-synchronous" I/O read/write operations |
*/ |
|
/* |
* Since all CMA "thread-synchronous" I/O (read or write) operations on |
* U*ix follow the exact same structure, the wrapper routines have been |
* condensed into a macro. |
* |
* The steps performed are as follows: |
* 1. Check that the file descriptor is a legitimate value. |
* 2. Check that the entry in the CMA file "database" which corresponds to |
* the file descriptor indicates that the "file" was "opened" by CMA. |
* 3. Reserve the file, to serialized access to files. This not only |
* simplifies things, but also defends against non-reentrancy. |
* 4. If the "file" is "set" for non-blocking I/O, check if we |
* have actually set the file non-blocking yet, and if not do so. |
* Then, issue the I/O operantion. |
* Success or failure is returned immediately, after unreserving the |
* file. If the error indicates that the operation would have caused |
* the process to block, continue to the next step. |
* 5. The I/O prolog adds this "file" to the global bit mask, which |
* represents all "files" which have threads waiting to perform I/O on |
* them, and causes the thread to block on the condition variable for |
* this "file". Periodically, a select is done on this global bit |
* mask, and the condition variables corresponding to "files" which |
* are ready for I/O are signaled, releasing those waiting threads to |
* perform their I/O. |
* 6. When the thread returns from the I/O prolog, it can (hopefully) |
* perform its operation without blocking the process. |
* 7. The I/O epilog clears the bit in the global mask and/or signals the |
* the next thread waiting for this "file", as appropriate. |
* 8. If the I/O failed, continue to loop. |
* 9. Finally, the "file" is unreserved, as we're done with it, and the |
* result of the operation is returned. |
* |
* |
* Note: currently, we believe that timeslicing which is based on the |
* virtual-time timer does not cause system calls to return EINTR. |
* Threfore, any EINTR returns are relayed directly to the caller. |
* On platforms which do not support a virtual-time timer, the code |
* should probably catch EINTR returns and restart the system call. |
*/ |
|
/* |
* This macro is used for both read-type and write-type functions. |
* |
* Note: the second call to "func" may require being bracketed in a |
* cma__interrupt_disable/cma__interrupt_enable pair, but we'll |
* wait and see if this is necessary. |
*/ |
#define cma__ts_func(func,fd,arglist,type,post_process) { \ |
cma_t_integer __res__; \ |
cma_t_boolean __done__ = cma_c_false; \ |
if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \ |
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \ |
cma__fd_reserve (fd); \ |
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \ |
if (cma__issue_io_call(fd)) {\ |
if ((!cma__g_file[fd]->set_non_blocking) && \ |
(cma__g_file[fd]->non_blocking == cma_c_true)) \ |
cma__set_nonblocking(fd); \ |
cma__interrupt_disable (0); \ |
TRY { \ |
__res__ = func arglist; \ |
} \ |
CATCH_ALL { \ |
cma__interrupt_enable (0); \ |
cma__fd_unreserve (fd); \ |
RERAISE; \ |
} \ |
ENDTRY \ |
cma__interrupt_enable (0); \ |
if ((__res__ != -1) \ |
|| (!cma__is_blocking (errno)) \ |
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \ |
__done__ = cma_c_true; \ |
} \ |
if (__done__) { \ |
cma__fd_unreserve (fd); \ |
} \ |
else { \ |
TRY { \ |
cma__io_prolog (type, fd); \ |
while (!__done__) { \ |
cma__io_wait (type, fd); \ |
__res__ = func arglist; \ |
if ((__res__ != -1) \ |
|| (!cma__is_blocking (errno)) \ |
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \ |
__done__ = cma_c_true; \ |
} \ |
} \ |
FINALLY { \ |
cma__io_epilog (type, fd); \ |
cma__fd_unreserve (fd); \ |
} \ |
ENDTRY \ |
} \ |
if (__res__ != -1) post_process; \ |
return __res__; \ |
} |
|
/* |
* Since most CMA "thread-synchronous" I/O ("open"-type) operations on |
* U*ix follow the exact same structure, the wrapper routines have been |
* condensed into a macro. |
* |
* The steps performed are as follows: |
* 1. Issue the open function. |
* 2. If the value returned indicates an error, return it to the caller. |
* 3. If the file descriptor returned is larger than what we think is the |
* maximum value (ie if it is too big for our database) then bugcheck. |
* 4. "Open" the "file" in the CMA file database. |
* 5. Return the file descriptor value to the caller. |
* |
* FIX-ME: for the time being, if the I/O operation returns EINTR, we |
* simply return it to the caller; eventually, we should catch this |
* and "do the right thing" (if we can figure out what that is). |
*/ |
|
/* |
* This macro is used for all "open"-type functions which return a single file |
* desciptor by immediate value. |
*/ |
#define cma__ts_open(func,arglist,post_process) { \ |
int __fd__; \ |
TRY { \ |
cma__int_init (); \ |
cma__int_lock (cma__g_io_data_mutex); \ |
__fd__ = func arglist; \ |
cma__int_unlock (cma__g_io_data_mutex); \ |
if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \ |
post_process; \ |
} \ |
CATCH_ALL \ |
{ \ |
cma__set_errno (EBADF); \ |
__fd__ = -1; \ |
} \ |
ENDTRY \ |
if (__fd__ >= cma__g_mx_file) \ |
cma__bugcheck ("cma__ts_open: fd is too large"); \ |
return __fd__; \ |
} |
/* |
* This macro is used for all "open"-type functions which return a pair of file |
* desciptors by reference parameter. |
*/ |
#define cma__ts_open2(func,fdpair,arglist,post_process) { \ |
int __res__; \ |
TRY { \ |
cma__int_init (); \ |
cma__int_lock (cma__g_io_data_mutex); \ |
__res__ = func arglist; \ |
cma__int_unlock (cma__g_io_data_mutex); \ |
if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \ |
&& fdpair[1] < cma__g_mx_file) \ |
post_process; \ |
} \ |
CATCH_ALL \ |
{ \ |
cma__set_errno (EBADF); \ |
__res__ = -1; \ |
} \ |
ENDTRY \ |
if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \ |
cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \ |
return __res__; \ |
} |
|
/* |
* INTERNAL INTERFACES |
*/ |
extern void cma__close_general (int); |
|
extern void cma__init_thread_io (void); |
|
extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *); |
|
extern void cma__io_epilog (cma__t_io_type,int); |
|
extern void cma__io_prolog (cma__t_io_type,int); |
|
extern void cma__io_wait (cma__t_io_type,int); |
|
extern void cma__open_general (int); |
|
extern void cma__reinit_thread_io (int); |
|
extern void cma__set_nonblocking (int); |
|
extern void cma__set_user_nonblock_flags (int,int); |
|
extern cma_t_boolean cma__is_open (int); |
|
#endif |
/cma_handle.h
0,0 → 1,182
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for handles |
*/ |
|
#ifndef CMA_HANDLE |
#define CMA_HANDLE |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma_defs.h> |
#include <cma_attr.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#define cma__validate_attr(handle) \ |
((cma__t_int_attr *)cma__validate_handle ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_attr)) |
|
#define cma__validate_cv(handle) \ |
((cma__t_int_cv *)cma__validate_handle ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_cv)) |
|
#define cma__validate_mutex(handle) \ |
((cma__t_int_mutex *)cma__validate_handle ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_mutex)) |
|
#define cma__validate_tcb(handle) \ |
((cma__t_int_tcb *)cma__validate_handle ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_tcb)) |
|
#define cma__validate_stack(handle) \ |
((cma__t_int_stack *)cma__validate_handle ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_stack)) |
|
#define cma__validate_null_attr(handle) \ |
((cma__t_int_attr *)cma__validate_handle_null ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_attr)) |
|
#define cma__validate_null_cv(handle) \ |
((cma__t_int_cv *)cma__validate_handle_null ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_cv)) |
|
#define cma__validate_null_mutex(handle) \ |
((cma__t_int_mutex *)cma__validate_handle_null ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_mutex)) |
|
#define cma__validate_null_tcb(handle) \ |
((cma__t_int_tcb *)cma__validate_handle_null ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_tcb)) |
|
#define cma__validate_null_stack(handle) \ |
((cma__t_int_stack *)cma__validate_handle_null ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_stack)) |
|
#define cma__val_attr_stat(handle,obj) \ |
cma__val_hand_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_attr, \ |
(cma__t_object **)obj) |
|
#define cma__val_cv_stat(handle,obj) \ |
cma__val_hand_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_cv, \ |
(cma__t_object **)obj) |
|
#define cma__val_mutex_stat(handle,obj) \ |
cma__val_hand_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_mutex, \ |
(cma__t_object **)obj) |
|
#define cma__val_tcb_stat(handle) \ |
cma__val_hand_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_tcb, \ |
(cma__t_object **)obj) |
|
#define cma__val_stack_stat(handle,obj) \ |
cma__val_hand_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_stack, \ |
(cma__t_object **)obj) |
|
#define cma__val_nullattr_stat(handle,obj) \ |
cma__val_handnull_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_attr, \ |
(cma__t_object **)obj) |
|
#define cma__val_nullcv_stat(handle,obj) \ |
cma__val_handnull_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_cv, \ |
(cma__t_object **)obj) |
|
#define cma__val_nullmutex_stat(handle,obj) \ |
cma__val_handnull_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_mutex, \ |
(cma__t_object **)obj) |
|
#define cma__val_nulltcb_stat(handle,obj) \ |
cma__val_handnull_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_tcb, \ |
(cma__t_object **)obj) |
|
#define cma__val_nullstack_stat(handle) \ |
cma__val_handnull_stat ( \ |
(cma_t_handle *)(handle), \ |
cma__c_obj_stack, \ |
(cma__t_object **)obj) |
|
/* |
* TYPEDEFS |
*/ |
|
/* |
* Internal format of a handle (to the outside world it's an array of two |
* addresses, but we know better). |
*/ |
typedef struct CMA__T_INT_HANDLE { |
cma__t_object *pointer; /* Address of internal structure */ |
cma__t_short sequence; /* Sequence number of object */ |
cma__t_short type; /* Type code of object */ |
} cma__t_int_handle; |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern void cma__clear_handle (cma_t_handle *); |
|
extern void cma__object_to_handle (cma__t_object *,cma_t_handle *); |
|
extern cma__t_int_attr * cma__validate_default_attr (cma_t_handle *); |
|
extern cma_t_status cma__val_defattr_stat (cma_t_handle *,cma__t_int_attr **); |
|
extern cma__t_object * cma__validate_handle (cma_t_handle *,cma_t_natural ); |
|
extern cma_t_status cma__val_hand_stat (cma_t_handle *,cma_t_natural,cma__t_object **); |
|
extern cma__t_object *cma__validate_handle_null (cma_t_handle *,cma_t_natural); |
|
extern cma_t_status cma__val_handnull_stat (cma_t_handle *,cma_t_natural,cma__t_object **); |
|
#endif |
/AT386/cma_thread_io.h
0,0 → 1,457
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for thread synchrounous I/O |
*/ |
|
#ifndef CMA_THREAD_IO |
#define CMA_THREAD_IO |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma_config.h> |
#include <sys/file.h> |
#include <cma.h> |
#include <sys/types.h> |
#include <sys/time.h> |
#include <cma_init.h> |
#include <cma_errors.h> |
|
/* |
* CONSTANTS |
*/ |
|
/* |
* Define symbols which indicate whether to compile code for obsolete |
* "non-blocking mode" flags: FNDELAY and FNBLOCK. If the obsolete |
* symbols are defined, and if their replacement symbols are defined |
* and are different or if they are undefined, then define a symbol |
* that says to compile the code in; otherwise no code will be compiled |
* for these obsolete symbols. |
*/ |
#ifdef FNDELAY |
# ifdef O_NDELAY |
# if O_NDELAY != FNDELAY |
# define _CMA_FNDELAY_ |
# endif |
# else |
# define _CMA_FNDELAY_ |
# endif |
#endif |
|
#ifdef FNBLOCK |
# ifdef O_NONBLOCK |
# if O_NONBLOCK != FNBLOCK |
# define _CMA_FNBLOCK_ |
# endif |
# else |
# define _CMA_FNBLOCK_ |
# endif |
#endif |
|
|
extern cma_t_boolean cma_is_open(int); |
/* |
* Maximum number of files (ie, max_fd+1) |
*/ |
#define cma__c_mx_file FD_SETSIZE |
|
/* |
* Number of bits per file descriptor bit mask (ie number of bytes * bits/byte) |
*/ |
#define cma__c_nbpm NFDBITS |
|
/* |
* TYPE DEFINITIONS |
*/ |
|
typedef enum CMA__T_IO_TYPE { |
cma__c_io_read = 0, |
cma__c_io_write = 1, |
cma__c_io_except = 2 |
} cma__t_io_type; |
#define cma__c_max_io_type 2 |
|
/* |
* From our local <sys/types.h>: |
* |
* typedef long fd_mask; |
* |
* typedef struct fd_set { |
* fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; |
* } fd_set; |
* |
*/ |
typedef fd_mask cma__t_mask; |
typedef fd_set cma__t_file_mask; |
|
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* Maximum number of files (ie, max_fd+1) as determined by getdtablesize(). |
*/ |
extern int cma__g_mx_file; |
|
/* |
* Number of submasks (ie "int" sized chunks) per file descriptor mask as |
* determined by getdtablesize(). |
*/ |
extern int cma__g_nspm; |
|
/* |
* MACROS |
*/ |
|
/* |
* Define a constant for the errno value which indicates that the requested |
* operation was not performed because it would block the process. |
*/ |
# define cma__is_blocking(s) \ |
((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \ |
(s == EALREADY) || (s == EDEADLK)) |
|
/* |
* It is necessary to issue an I/O function, before calling cma__io_wait() |
* in the following cases: |
* |
* * This file descriptor has been set non-blocking by CMA |
* * This file descriptor has been set non-blocking by the user. |
*/ |
|
#define cma__issue_io_call(fd) \ |
( (cma__g_file[fd]->non_blocking) || \ |
(cma__g_file[fd]->user_fl.user_non_blocking) ) |
|
|
#define cma__set_user_nonblocking(flags) \ |
|
/* |
* Determine if the file is open |
*/ |
/* |
* If the file gets closed while waiting for the mutex cma__g_file[rfd] |
* gets set to null. This results in a crash if NDEBUG is set to 0 |
* since cma__int_lock tries to dereference it to set the mutex ownership |
* after it gets the mutex. The following will still set the ownership |
* in cma__int_lock so we'll set it back to noone if cma__g_file is null |
* when we come back just in case it matters. It shouldn't since its no |
* longer in use but..... |
* Callers of this should recheck cma__g_file after the reservation to |
* make sure continueing makes sense. |
*/ |
#define cma__fd_reserve(rfd) \ |
{ \ |
cma__t_int_mutex *__mutex__; \ |
__mutex__ = cma__g_file[rfd]->mutex; \ |
cma__int_lock (__mutex__); \ |
if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \ |
cma__int_unlock(__mutex__); \ |
} |
|
|
/* |
* Unreserve a file descriptor |
*/ |
#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex) |
|
/* |
* AND together two select file descriptor masks |
*/ |
#define cma__fdm_and(target,a,b) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) \ |
(target)->fds_bits[__i__] = \ |
(a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \ |
} |
|
/* |
* Clear a bit in a select file descriptor mask |
* |
* FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_clr_bit(n,p) FD_CLR (n, p) |
|
/* |
* Copy the contents of one file descriptor mask into another. If the |
* destination operand is null, do nothing; if the source operand is null, |
* simply zero the destination. |
*/ |
#define cma__fdm_copy(src,dst,nfds) { \ |
if (dst) \ |
if (src) { \ |
cma__t_mask *__s__ = (cma__t_mask *)(src); \ |
cma__t_mask *__d__ = (cma__t_mask *)(dst); \ |
int __i__; \ |
for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \ |
*__d__++ = *__s__++; \ |
} \ |
else \ |
cma__fdm_zero (dst); \ |
} |
|
/* |
* To increment count for each bit set in fd - mask |
*/ |
#define cma__fdm_count_bits(map,count) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) { \ |
cma__t_mask __tm__; \ |
__tm__ = (map)->fds_bits[__i__]; \ |
while(__tm__) { \ |
(count)++; \ |
__tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \ |
} \ |
} \ |
} |
|
/* |
* Test if a bit is set in a select file descriptor mask |
* |
* FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_is_set(n,p) FD_ISSET (n, p) |
|
/* |
* OR together two select file descriptor masks |
*/ |
#define cma__fdm_or(target,a,b) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) \ |
(target)->fds_bits[__i__] = \ |
(a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \ |
} |
|
/* |
* Set a bit in a select file descriptor mask |
* |
* FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_set_bit(n,p) FD_SET (n, p) |
|
/* |
* Clear a select file descriptor mask. |
*/ |
#define cma__fdm_zero(n) \ |
cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask)) |
|
|
|
/* |
* CMA "thread-synchronous" I/O read/write operations |
*/ |
|
/* |
* Since all CMA "thread-synchronous" I/O (read or write) operations on |
* U*ix follow the exact same structure, the wrapper routines have been |
* condensed into a macro. |
* |
* The steps performed are as follows: |
* 1. Check that the file descriptor is a legitimate value. |
* 2. Check that the entry in the CMA file "database" which corresponds to |
* the file descriptor indicates that the "file" was "opened" by CMA. |
* 3. Reserve the file, to serialized access to files. This not only |
* simplifies things, but also defends against non-reentrancy. |
* 4. If the "file" is "set" for non-blocking I/O, check if we |
* have actually set the file non-blocking yet, and if not do so. |
* Then, issue the I/O operantion. |
* Success or failure is returned immediately, after unreserving the |
* file. If the error indicates that the operation would have caused |
* the process to block, continue to the next step. |
* 5. The I/O prolog adds this "file" to the global bit mask, which |
* represents all "files" which have threads waiting to perform I/O on |
* them, and causes the thread to block on the condition variable for |
* this "file". Periodically, a select is done on this global bit |
* mask, and the condition variables corresponding to "files" which |
* are ready for I/O are signaled, releasing those waiting threads to |
* perform their I/O. |
* 6. When the thread returns from the I/O prolog, it can (hopefully) |
* perform its operation without blocking the process. |
* 7. The I/O epilog clears the bit in the global mask and/or signals the |
* the next thread waiting for this "file", as appropriate. |
* 8. If the I/O failed, continue to loop. |
* 9. Finally, the "file" is unreserved, as we're done with it, and the |
* result of the operation is returned. |
* |
* |
* Note: currently, we believe that timeslicing which is based on the |
* virtual-time timer does not cause system calls to return EINTR. |
* Threfore, any EINTR returns are relayed directly to the caller. |
* On platforms which do not support a virtual-time timer, the code |
* should probably catch EINTR returns and restart the system call. |
*/ |
|
/* |
* This macro is used for both read-type and write-type functions. |
* |
* Note: the second call to "func" may require being bracketed in a |
* cma__interrupt_disable/cma__interrupt_enable pair, but we'll |
* wait and see if this is necessary. |
*/ |
#define cma__ts_func(func,fd,arglist,type,post_process) { \ |
cma_t_integer __res__; \ |
cma_t_boolean __done__ = cma_c_false; \ |
if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \ |
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \ |
cma__fd_reserve (fd); \ |
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \ |
if (cma__issue_io_call(fd)) {\ |
if ((!cma__g_file[fd]->set_non_blocking) && \ |
(cma__g_file[fd]->non_blocking == cma_c_true)) \ |
cma__set_nonblocking(fd); \ |
cma__interrupt_disable (0); \ |
TRY { \ |
__res__ = func arglist; \ |
} \ |
CATCH_ALL { \ |
cma__interrupt_enable (0); \ |
cma__fd_unreserve (fd); \ |
RERAISE; \ |
} \ |
ENDTRY \ |
cma__interrupt_enable (0); \ |
if ((__res__ != -1) \ |
|| (!cma__is_blocking (errno)) \ |
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \ |
__done__ = cma_c_true; \ |
} \ |
if (__done__) { \ |
cma__fd_unreserve (fd); \ |
} \ |
else { \ |
TRY { \ |
cma__io_prolog (type, fd); \ |
while (!__done__) { \ |
cma__io_wait (type, fd); \ |
__res__ = func arglist; \ |
if ((__res__ != -1) \ |
|| (!cma__is_blocking (errno)) \ |
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \ |
__done__ = cma_c_true; \ |
} \ |
} \ |
FINALLY { \ |
cma__io_epilog (type, fd); \ |
cma__fd_unreserve (fd); \ |
} \ |
ENDTRY \ |
} \ |
if (__res__ != -1) post_process; \ |
return __res__; \ |
} |
|
/* |
* Since most CMA "thread-synchronous" I/O ("open"-type) operations on |
* U*ix follow the exact same structure, the wrapper routines have been |
* condensed into a macro. |
* |
* The steps performed are as follows: |
* 1. Issue the open function. |
* 2. If the value returned indicates an error, return it to the caller. |
* 3. If the file descriptor returned is larger than what we think is the |
* maximum value (ie if it is too big for our database) then bugcheck. |
* 4. "Open" the "file" in the CMA file database. |
* 5. Return the file descriptor value to the caller. |
* |
* FIX-ME: for the time being, if the I/O operation returns EINTR, we |
* simply return it to the caller; eventually, we should catch this |
* and "do the right thing" (if we can figure out what that is). |
*/ |
|
/* |
* This macro is used for all "open"-type functions which return a single file |
* desciptor by immediate value. |
*/ |
#define cma__ts_open(func,arglist,post_process) { \ |
int __fd__; \ |
TRY { \ |
cma__int_init (); \ |
cma__int_lock (cma__g_io_data_mutex); \ |
__fd__ = func arglist; \ |
cma__int_unlock (cma__g_io_data_mutex); \ |
if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \ |
post_process; \ |
} \ |
CATCH_ALL \ |
{ \ |
cma__set_errno (EBADF); \ |
__fd__ = -1; \ |
} \ |
ENDTRY \ |
if (__fd__ >= cma__g_mx_file) \ |
cma__bugcheck ("cma__ts_open: fd is too large"); \ |
return __fd__; \ |
} |
/* |
* This macro is used for all "open"-type functions which return a pair of file |
* desciptors by reference parameter. |
*/ |
#define cma__ts_open2(func,fdpair,arglist,post_process) { \ |
int __res__; \ |
TRY { \ |
cma__int_init (); \ |
cma__int_lock (cma__g_io_data_mutex); \ |
__res__ = func arglist; \ |
cma__int_unlock (cma__g_io_data_mutex); \ |
if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \ |
&& fdpair[1] < cma__g_mx_file) \ |
post_process; \ |
} \ |
CATCH_ALL \ |
{ \ |
cma__set_errno (EBADF); \ |
__res__ = -1; \ |
} \ |
ENDTRY \ |
if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \ |
cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \ |
return __res__; \ |
} |
|
/* |
* INTERNAL INTERFACES |
*/ |
extern void cma__close_general (int); |
|
extern void cma__init_thread_io (void); |
|
extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *); |
|
extern void cma__io_epilog (cma__t_io_type,int); |
|
extern void cma__io_prolog (cma__t_io_type,int); |
|
extern void cma__io_wait (cma__t_io_type,int); |
|
extern void cma__open_general (int); |
|
extern void cma__reinit_thread_io (int); |
|
extern void cma__set_nonblocking (int); |
|
extern void cma__set_user_nonblock_flags (int,int); |
|
extern cma_t_boolean cma__is_open (int); |
|
|
#endif |
/cma_mutex.h
0,0 → 1,230
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for mutex operations |
*/ |
|
#ifndef CMA_MUTEX |
#define CMA_MUTEX |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma.h> |
#include <cma_attr.h> |
#include <cma_defs.h> |
#include <cma_semaphore_defs.h> |
#include <cma_sequence.h> |
#include <cma_tcb_defs.h> |
#include <cma_stack.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
/* |
* TYPEDEFS |
*/ |
|
typedef struct CMA__T_INT_MUTEX { |
cma__t_object header; /* Common header (sequence, type) */ |
cma__t_int_attr *attributes; /* Back link */ |
cma__t_int_tcb *owner; /* Current owner (if any) */ |
cma_t_integer nest_count; /* Nesting level for recursive mutex */ |
cma__t_atomic_bit *unlock; /* Pointer used for unlock operation */ |
cma__t_atomic_bit lock; /* Set if currently locked */ |
struct CMA__T_INT_MUTEX *int_lock; /* Internal protection for mutex */ |
cma__t_atomic_bit event; /* Clear when unlock requires action */ |
cma__t_atomic_bit waiters; /* Clear when threads are waiting */ |
cma__t_atomic_bit bitbucket; /* Fake bit to keep friendlies locked */ |
cma_t_mutex_kind mutex_kind; /* Kind of mutex */ |
cma__t_semaphore semaphore; /* Semaphore for low-level wait */ |
} cma__t_int_mutex; |
|
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* Lock a mutex (internal) |
* |
* FORMAL PARAMETERS: |
* |
* mutex Pointer to mutex object to lock |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* none |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#ifdef NDEBUG |
# define cma__int_lock(mutex) { \ |
if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \ |
cma_t_status res;\ |
res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \ |
if (res != cma_s_normal) cma__error (res); \ |
} \ |
} |
#else |
# define cma__int_lock(mutex) { \ |
cma__t_int_tcb *__ltcb__; \ |
__ltcb__ = cma__get_self_tcb (); \ |
if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \ |
cma_t_status res;\ |
res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \ |
if (res != cma_s_normal) cma__error (res); \ |
} \ |
((cma__t_int_mutex *)mutex)->owner = __ltcb__; \ |
} |
#endif |
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* Unlock a mutex (internal) |
* |
* FORMAL PARAMETERS: |
* |
* mutex Pointer to mutex object to unlock |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* none |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#ifdef NDEBUG |
# define cma__int_unlock(mutex) { \ |
cma__unset (((cma__t_int_mutex *)mutex)->unlock); \ |
if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \ |
cma_t_status res;\ |
res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \ |
if (res != cma_s_normal) cma__error (res); \ |
} \ |
} |
#else |
# define cma__int_unlock(mutex) { \ |
cma__t_int_tcb *__utcb__; \ |
__utcb__ = cma__get_self_tcb (); \ |
if (((cma__t_int_mutex *)mutex)->mutex_kind == cma_c_mutex_fast) { \ |
cma__assert_warn ( \ |
(__utcb__ == ((cma__t_int_mutex *)mutex)->owner), \ |
"attempt to release mutx owned by another thread"); \ |
((cma__t_int_mutex *)mutex)->owner = (cma__t_int_tcb *)cma_c_null_ptr; \ |
} \ |
cma__unset (((cma__t_int_mutex *)mutex)->unlock); \ |
if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \ |
cma_t_status res;\ |
res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \ |
if (res != cma_s_normal) cma__error (res); \ |
} \ |
} |
#endif |
|
/* |
* FUNCTIONAL DESCRIPTION: |
* |
* cma__int_mutex_delete - Performs work for cma_mutex_delete |
* |
* FORMAL PARAMETERS: |
* |
* cma__t_mutex _mutex_ - Mutex to be deleted |
* |
* IMPLICIT INPUTS: |
* |
* none |
* |
* IMPLICIT OUTPUTS: |
* |
* none |
* |
* FUNCTION VALUE: |
* |
* none |
* |
* SIDE EFFECTS: |
* |
* none |
*/ |
#define cma__int_mutex_delete(_mutex_) { \ |
cma__t_int_mutex *_int_mutex_; \ |
_int_mutex_ = cma__validate_null_mutex (_mutex_); \ |
if (_int_mutex_ == (cma__t_int_mutex *)cma_c_null_ptr) \ |
return; \ |
if (cma__int_mutex_locked (_int_mutex_)) \ |
cma__error (cma_s_in_use); \ |
cma__free_mutex (_int_mutex_); \ |
cma__clear_handle (_mutex_); \ |
} |
|
|
/* |
* GLOBAL DATA |
*/ |
|
extern cma__t_sequence cma__g_mutex_seq; |
extern cma__t_int_mutex *cma__g_global_lock; |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern void cma__destroy_mutex (cma__t_int_mutex *); |
|
extern void cma__free_mutex (cma__t_int_mutex *); |
|
extern void cma__free_mutex_nolock (cma__t_int_mutex *); |
|
extern cma__t_int_mutex * cma__get_first_mutex (cma__t_int_attr *); |
|
extern cma__t_int_mutex * cma__get_mutex (cma__t_int_attr *); |
|
extern void cma__init_mutex (void); |
|
extern cma_t_status cma__int_mutex_block (cma__t_int_mutex *); |
|
extern cma_t_boolean cma__int_mutex_locked (cma__t_int_mutex *); |
|
extern cma_t_boolean cma__int_try_lock (cma__t_int_mutex *); |
|
extern cma_t_status cma__int_mutex_unblock (cma__t_int_mutex *); |
|
extern cma_t_boolean cma__mutex_locked (cma_t_mutex); |
|
extern void cma__reinit_mutex (cma_t_integer); |
|
#endif |
/cma_deb_core.h
0,0 → 1,164
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* This file defines the internal interface to the core of CMA |
* debugging services. (The client interface to debugging services |
* is provided by cma_debug_client.h). |
*/ |
|
#ifndef CMA_DEB_CORE |
#define CMA_DEB_CORE |
|
/* |
* INCLUDE FILES |
*/ |
#include <cma.h> |
#include <cma_mutex.h> |
#include <cma_queue.h> |
#include <cma_tcb_defs.h> |
#include <cma_util.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
|
/* |
* TYPEDEFS |
*/ |
|
/*FIX-ME* Need to use sizes that are platform specific */ |
typedef long int cma___t_debug_ctx[17]; |
|
/* |
* Type defing the format of known object lists |
*/ |
typedef struct CMA__T_KNOWN_OBJECT { |
cma__t_queue queue; /* Queue header for known objects */ |
cma__t_int_mutex *mutex; /* Mutex to control access to queue */ |
} cma__t_known_object; |
|
|
/* |
* Type defining the registration for one debug client (e.g. Ada) |
*/ |
typedef struct CMA__T_DEB_REGISTRY { |
cma_t_address entry; /* Client's debug entry point */ |
cma_t_key key; /* Client's context key */ |
cma_t_integer fac; /* Client's debug facility number */ |
cma_t_boolean has_prolog; /* Client's TCBs have std prolog */ |
} cma__t_deb_registry; |
|
#define cma__c_deb_max_clients 10 |
|
/* |
* Type defining the global debugging state for all threads. |
*/ |
typedef struct CMA__T_DEBUG_STATE { |
/* |
* The following flag is set if changes were made while in the |
* debugger that may make the ready lists inconsistent. For |
* example, if a thread priority is changed in the debugger, the |
* thread is not moved between queues. Making things consistent |
* is deferred to when the dispatcher is next invoked -- which we |
* try to make very soon. |
*/ |
cma_t_boolean is_inconsistency; /* Ready lists are inconsistent */ |
|
|
cma_t_boolean events_enabled; /* Set if _any_ event is enabled */ |
cma_t_boolean flags[cma__c_debevt__dim]; |
/* Which events are enabled */ |
cma__t_int_tcb *next_to_run; /* TCB of thread to run next */ |
|
cma__t_int_mutex *mutex; /* Mutex for registering clients */ |
cma_t_integer client_count; /* Count of debug clients */ |
cma__t_deb_registry clients[cma__c_deb_max_clients+1]; |
/* Array of current debug clients */ |
} cma__t_debug_state; |
|
|
/* |
* Routine that will symbolize and address and print it. |
*/ |
typedef void (*cma__t_print_symbol) (cma_t_address); |
|
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* Variable holding the global debugging state |
* |
* (This is primarily written by the debugger interface and read |
* by the thread dispatcher). |
*/ |
extern cma__t_debug_state cma__g_debug_state; |
|
/* |
* Known object queues |
*/ |
extern cma__t_known_object cma__g_known_atts; |
extern cma__t_known_object cma__g_known_cvs; |
extern cma__t_known_object cma__g_known_mutexes; |
extern cma__t_known_object cma__g_known_threads; |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
/* Get information while in debugger context */ |
extern void cma__deb_get |
(cma__t_int_tcb *,cma_t_debug_get,cma_t_address,cma_t_integer,cma_t_integer); |
|
/* Set information while in debugger context */ |
extern void cma__deb_set (cma__t_int_tcb *,cma_t_debug_set,cma_t_address,cma_t_integer); |
|
extern void cma__init_debug (void); |
|
extern void cma__reinit_debug (cma_t_integer); |
|
extern void cma__deb_anytcb_to_tcb (cma_t_tcb_header *,cma__t_int_tcb **); |
|
extern void cma__deb_fac_to_client (cma_t_integer,cma_t_key *); |
|
extern void cma__deb_get_client_info (cma_t_key,cma_t_address *,cma_t_boolean *); |
|
extern void cma__deb_get_context (cma__t_int_tcb *,cma_t_key,cma_t_address *); |
|
extern cma__t_int_tcb *cma__deb_get_self_tcb (void); |
|
extern void cma__deb_get_time_slice (cma_t_interval *); |
|
extern cma__t_int_tcb *cma__deb_next_tcb |
(cma__t_int_tcb *,cma_t_integer *,cma_t_integer *,cma_t_boolean *); |
|
extern cma_t_boolean cma__deb_set_alert (cma__t_int_tcb *); |
|
extern void cma__deb_set_next_thread (cma__t_int_tcb *); |
|
extern void cma__deb_set_force_dispatch (cma_t_address ); |
|
extern void cma__deb_set_time_slice (cma_t_interval); |
|
extern void cma__deb_show_thread |
(cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma___t_debug_ctx,cma__t_eol_routine, |
cma__t_eol_routine,cma__t_print_symbol); |
|
extern void |
cma__deb_show_stats (cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma__t_eol_routine,cma__t_eol_routine,cma__t_print_symbol); |
#endif |
/cma_init.h
0,0 → 1,114
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for CMA initialization |
*/ |
|
#ifndef CMA_INIT |
#define CMA_INIT |
|
/* |
* INCLUDE FILES |
*/ |
#include <dce/cma_host.h> |
#include <cma_errors.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#define cma__c_env_maxattr 0 |
#define cma__c_env_minattr 1 |
#define cma__c_env_maxcond 2 |
#define cma__c_env_mincond 3 |
#define cma__c_env_maxmutex 4 |
#define cma__c_env_minmutex 5 |
#define cma__c_env_maxthread 6 |
#define cma__c_env_minthread 7 |
#define cma__c_env_maxcluster 8 |
#define cma__c_env_mincluster 9 |
#define cma__c_env_maxvp 10 |
#define cma__c_env_multiplex 11 |
#define cma__c_env_trace 12 |
#define cma__c_env_trace_file 13 |
|
#define cma__c_env_count 13 |
|
|
/* |
* cma__int_init |
* |
* Initialize the main body of CMA exactly once. |
* |
* We raise an exception if, for some odd reason, there are already threads |
* in the environment (e.g. kernel threads), and one of them is trying to |
* initialize CMA before the first thread got all the way through the actual |
* initialization. This code maintains the invariants: "after successfully |
* calling CMA_INIT, you can call any CMA function", and "CMA is actually |
* initialized at most once". |
*/ |
/*#ifndef _HP_LIBC_R */ |
|
#if defined _HP_LIBC_R ||(defined(SNI_SVR4) && !defined(CMA_INIT_NEEDED)) |
# define cma__int_init() |
#else |
# define cma__int_init() { \ |
if (!cma__tac_isset(&cma__g_init_started)) { \ |
if (!cma__test_and_set (&cma__g_init_started)) { \ |
cma__init_static (); \ |
cma__test_and_set (&cma__g_init_done); \ |
} \ |
else if (!cma__tac_isset (&cma__g_init_done)) { \ |
cma__error (cma_s_inialrpro); \ |
}}} |
#endif |
|
/* |
* TYPEDEFS |
*/ |
|
typedef enum CMA__T_ENV_TYPE { |
cma__c_env_type_int, |
cma__c_env_type_file |
} cma__t_env_type; |
|
typedef struct CMA__T_ENV { |
char *name; /* Name of environment variable */ |
cma__t_env_type type; /* Type of variable */ |
cma_t_integer value; /* Numeric value of the variable */ |
} cma__t_env; |
|
/* |
* GLOBAL DATA |
*/ |
|
extern cma__t_env cma__g_env[cma__c_env_count]; |
extern cma__t_atomic_bit cma__g_init_started; |
extern cma__t_atomic_bit cma__g_init_done; |
extern char *cma__g_version; |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern void |
cma__init_static (void); /* Initialize static data */ |
|
#if _CMA_OS_ != _CMA__VMS |
extern void cma__init_atfork (void); |
#endif |
|
#endif |
/cma_stack.h
0,0 → 1,83
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for stack management |
*/ |
#ifndef CMA_STACK |
#define CMA_STACK |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma_tcb_defs.h> |
#include <cma.h> |
#include <cma_attr.h> |
#include <cma_queue.h> |
#include <cma_stack_int.h> |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
#if _CMA_UNIPROCESSOR_ |
# define cma__get_self_tcb() (cma__g_current_thread) |
#endif |
|
/* |
* Round the given value (a) upto cma__g_chunk_size |
*/ |
#define cma__roundup_chunksize(a) (cma__roundup(a,cma__g_chunk_size)) |
|
/* |
* TYPEDEFS |
*/ |
|
/* |
* GLOBAL DATA |
*/ |
|
extern cma__t_list cma__g_stack_clusters; |
extern cma__t_int_tcb *cma__g_current_thread; |
extern cma_t_integer cma__g_chunk_size; |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern void cma__assign_stack (cma__t_int_stack *,cma__t_int_tcb *); |
|
extern void cma__free_stack (cma__t_int_stack *); |
|
extern void cma__free_stack_list (cma__t_queue *); |
|
#if !_CMA_UNIPROCESSOR_ |
extern cma__t_int_tcb * cma__get_self_tcb (void); |
#endif |
|
extern cma__t_int_tcb * cma__get_sp_tcb (cma_t_address); |
|
extern cma__t_int_stack * cma__get_stack (cma__t_int_attr *); |
|
extern void cma__init_stack (void); |
|
extern void cma__reinit_stack (cma_t_integer); |
|
#if _CMA_PROTECT_MEMORY_ |
extern void cma__remap_stack_holes (void); |
#endif |
|
#endif |
/RIOS/cma_thread_io.h
0,0 → 1,434
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for thread synchrounous I/O |
*/ |
|
#ifndef CMA_THREAD_IO |
#define CMA_THREAD_IO |
|
/* |
* INCLUDE FILES |
*/ |
|
#include <cma_config.h> |
#include <sys/select.h> |
#include <cma.h> |
#include <sys/types.h> |
#include <sys/time.h> |
#include <cma_init.h> |
#include <cma_errors.h> |
|
/* |
* CONSTANTS |
*/ |
|
/* |
* Maximum number of files (ie, max_fd+1) |
*/ |
#define cma__c_mx_file FD_SETSIZE |
|
/* |
* Number of bits per file descriptor bit mask (ie number of bytes * bits/byte) |
*/ |
#define cma__c_nbpm NFDBITS |
|
/* |
* TYPE DEFINITIONS |
*/ |
|
typedef enum CMA__T_IO_TYPE { |
cma__c_io_read = 0, |
cma__c_io_write = 1, |
cma__c_io_except = 2 |
} cma__t_io_type; |
#define cma__c_max_io_type 2 |
|
/* |
* From our local <sys/types.h>: |
* |
* typedef long fd_mask; |
* |
* typedef struct fd_set { |
* fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; |
* } fd_set; |
* |
*/ |
typedef fd_mask cma__t_mask; |
typedef fd_set cma__t_file_mask; |
|
|
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* Maximum number of files (ie, max_fd+1) as determined by getdtablesize(). |
*/ |
extern int cma__g_mx_file; |
|
/* |
* Number of submasks (ie "int" sized chunks) per file descriptor mask as |
* determined by getdtablesize(). |
*/ |
extern int cma__g_nspm; |
|
/* |
* MACROS |
*/ |
|
/* |
* Define a constant for the errno value which indicates that the requested |
* operation was not performed because it would block the process. |
*/ |
# define cma__is_blocking(s) \ |
((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \ |
(s == EALREADY) || (s == EDEADLK)) |
|
/* |
* It is necessary to issue an I/O function, before calling cma__io_wait() |
* in the following cases: |
* |
* * This file descriptor has been set non-blocking by CMA |
* * This file descriptor has been set non-blocking by the user. |
*/ |
|
#define cma__issue_io_call(fd) \ |
( (cma__g_file[fd]->non_blocking) || \ |
(cma__g_file[fd]->user_fl.user_non_blocking) ) |
|
|
#define cma__set_user_nonblocking(flags) \ |
|
/* |
* Determine if the file is open |
*/ |
/* |
* If the file gets closed while waiting for the mutex cma__g_file[rfd] |
* gets set to null. This results in a crash if NDEBUG is set to 0 |
* since cma__int_lock tries to dereference it to set the mutex ownership |
* after it gets the mutex. The following will still set the ownership |
* in cma__int_lock so we'll set it back to noone if cma__g_file is null |
* when we come back just in case it matters. It shouldn't since its no |
* longer in use but..... |
* Callers of this should recheck cma__g_file after the reservation to |
* make sure continueing makes sense. |
*/ |
#define cma__fd_reserve(rfd) \ |
{ \ |
cma__t_int_mutex *__mutex__; \ |
__mutex__ = cma__g_file[rfd]->mutex; \ |
cma__int_lock (__mutex__); \ |
if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \ |
cma__int_unlock(__mutex__); \ |
} |
|
|
/* |
* Unreserve a file descriptor |
*/ |
#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex) |
|
/* |
* AND together two select file descriptor masks |
*/ |
#define cma__fdm_and(target,a,b) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) \ |
(target)->fds_bits[__i__] = \ |
(a)->fds_bits[__i__] & (b)->fds_bits[__i__]; \ |
} |
|
/* |
* Clear a bit in a select file descriptor mask |
* |
* FD_CLR(n, p) := ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_clr_bit(n,p) FD_CLR (n, p) |
|
/* |
* Copy the contents of one file descriptor mask into another. If the |
* destination operand is null, do nothing; if the source operand is null, |
* simply zero the destination. |
*/ |
#define cma__fdm_copy(src,dst,nfds) { \ |
if (dst) \ |
if (src) { \ |
cma__t_mask *__s__ = (cma__t_mask *)(src); \ |
cma__t_mask *__d__ = (cma__t_mask *)(dst); \ |
int __i__; \ |
for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm) \ |
*__d__++ = *__s__++; \ |
} \ |
else \ |
cma__fdm_zero (dst); \ |
} |
|
/* |
* To increment count for each bit set in fd - mask |
*/ |
#define cma__fdm_count_bits(map,count) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) { \ |
cma__t_mask __tm__; \ |
__tm__ = (map)->fds_bits[__i__]; \ |
while(__tm__) { \ |
(count)++; \ |
__tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \ |
} \ |
} \ |
} |
|
/* |
* Test if a bit is set in a select file descriptor mask |
* |
* FD_ISSET(n,p) := ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_is_set(n,p) FD_ISSET (n, p) |
|
/* |
* OR together two select file descriptor masks |
*/ |
#define cma__fdm_or(target,a,b) \ |
{ \ |
int __i__ = cma__g_nspm; \ |
while (__i__--) \ |
(target)->fds_bits[__i__] = \ |
(a)->fds_bits[__i__] | (b)->fds_bits[__i__]; \ |
} |
|
/* |
* Set a bit in a select file descriptor mask |
* |
* FD_SET(n,p) := ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) |
*/ |
#define cma__fdm_set_bit(n,p) FD_SET (n, p) |
|
/* |
* Clear a select file descriptor mask. |
*/ |
#define cma__fdm_zero(n) \ |
cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask)) |
|
|
|
|
|
/* |
* CMA "thread-synchronous" I/O read/write operations |
*/ |
|
/* |
* Since all CMA "thread-synchronous" I/O (read or write) operations on |
* U*ix follow the exact same structure, the wrapper routines have been |
* condensed into a macro. |
* |
* The steps performed are as follows: |
* 1. Check that the file descriptor is a legitimate value. |
* 2. Check that the entry in the CMA file "database" which corresponds to |
* the file descriptor indicates that the "file" was "opened" by CMA. |
* 3. Reserve the file, to serialized access to files. This not only |
* simplifies things, but also defends against non-reentrancy. |
* 4. If the "file" is "set" for non-blocking I/O, check if we |
* have actually set the file non-blocking yet, and if not do so. |
* Then, issue the I/O operantion. |
* Success or failure is returned immediately, after unreserving the |
* file. If the error indicates that the operation would have caused |
* the process to block, continue to the next step. |
* 5. The I/O prolog adds this "file" to the global bit mask, which |
* represents all "files" which have threads waiting to perform I/O on |
* them, and causes the thread to block on the condition variable for |
* this "file". Periodically, a select is done on this global bit |
* mask, and the condition variables corresponding to "files" which |
* are ready for I/O are signaled, releasing those waiting threads to |
* perform their I/O. |
* 6. When the thread returns from the I/O prolog, it can (hopefully) |
* perform its operation without blocking the process. |
* 7. The I/O epilog clears the bit in the global mask and/or signals the |
* the next thread waiting for this "file", as appropriate. |
* 8. If the I/O failed, continue to loop. |
* 9. Finally, the "file" is unreserved, as we're done with it, and the |
* result of the operation is returned. |
* |
* |
* Note: currently, we believe that timeslicing which is based on the |
* virtual-time timer does not cause system calls to return EINTR. |
* Threfore, any EINTR returns are relayed directly to the caller. |
* On platforms which do not support a virtual-time timer, the code |
* should probably catch EINTR returns and restart the system call. |
*/ |
|
/* |
* This macro is used for both read-type and write-type functions. |
* |
* Note: the second call to "func" may require being bracketed in a |
* cma__interrupt_disable/cma__interrupt_enable pair, but we'll |
* wait and see if this is necessary. |
*/ |
#define cma__ts_func(func,fd,arglist,type,post_process) { \ |
cma_t_integer __res__; \ |
cma_t_boolean __done__ = cma_c_false; \ |
if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \ |
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \ |
cma__fd_reserve (fd); \ |
if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \ |
if (cma__issue_io_call(fd)) {\ |
if ((!cma__g_file[fd]->set_non_blocking) && \ |
(cma__g_file[fd]->non_blocking == cma_c_true)) \ |
cma__set_nonblocking(fd); \ |
cma__interrupt_disable (0); \ |
TRY { \ |
__res__ = func arglist; \ |
} \ |
CATCH_ALL { \ |
cma__interrupt_enable (0); \ |
cma__fd_unreserve (fd); \ |
RERAISE; \ |
} \ |
ENDTRY \ |
cma__interrupt_enable (0); \ |
if ((__res__ != -1) \ |
|| (!cma__is_blocking (errno)) \ |
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \ |
__done__ = cma_c_true; \ |
} \ |
if (__done__) { \ |
cma__fd_unreserve (fd); \ |
} \ |
else { \ |
TRY { \ |
cma__io_prolog (type, fd); \ |
while (!__done__) { \ |
cma__io_wait (type, fd); \ |
__res__ = func arglist; \ |
if ((__res__ != -1) \ |
|| (!cma__is_blocking (errno)) \ |
|| (cma__g_file[fd]->user_fl.user_non_blocking)) \ |
__done__ = cma_c_true; \ |
} \ |
} \ |
FINALLY { \ |
cma__io_epilog (type, fd); \ |
cma__fd_unreserve (fd); \ |
} \ |
ENDTRY \ |
} \ |
if (__res__ != -1) post_process; \ |
return __res__; \ |
} |
|
/* |
* Since most CMA "thread-synchronous" I/O ("open"-type) operations on |
* U*ix follow the exact same structure, the wrapper routines have been |
* condensed into a macro. |
* |
* The steps performed are as follows: |
* 1. Issue the open function. |
* 2. If the value returned indicates an error, return it to the caller. |
* 3. If the file descriptor returned is larger than what we think is the |
* maximum value (ie if it is too big for our database) then bugcheck. |
* 4. "Open" the "file" in the CMA file database. |
* 5. Return the file descriptor value to the caller. |
* |
* FIX-ME: for the time being, if the I/O operation returns EINTR, we |
* simply return it to the caller; eventually, we should catch this |
* and "do the right thing" (if we can figure out what that is). |
*/ |
|
/* |
* This macro is used for all "open"-type functions which return a single file |
* desciptor by immediate value. |
*/ |
#define cma__ts_open(func,arglist,post_process) { \ |
int __fd__; \ |
TRY { \ |
cma__int_init (); \ |
cma__int_lock (cma__g_io_data_mutex); \ |
__fd__ = func arglist; \ |
cma__int_unlock (cma__g_io_data_mutex); \ |
if (__fd__ >= 0 && __fd__ < cma__g_mx_file) \ |
post_process; \ |
} \ |
CATCH_ALL \ |
{ \ |
cma__set_errno (EBADF); \ |
__fd__ = -1; \ |
} \ |
ENDTRY \ |
if (__fd__ >= cma__g_mx_file) \ |
cma__bugcheck ("cma__ts_open: fd is too large"); \ |
return __fd__; \ |
} |
/* |
* This macro is used for all "open"-type functions which return a pair of file |
* desciptors by reference parameter. |
*/ |
#define cma__ts_open2(func,fdpair,arglist,post_process) { \ |
int __res__; \ |
TRY { \ |
cma__int_init (); \ |
cma__int_lock (cma__g_io_data_mutex); \ |
__res__ = func arglist; \ |
cma__int_unlock (cma__g_io_data_mutex); \ |
if (__res__ >= 0 && fdpair[0] < cma__g_mx_file \ |
&& fdpair[1] < cma__g_mx_file) \ |
post_process; \ |
} \ |
CATCH_ALL \ |
{ \ |
cma__set_errno (EBADF); \ |
__res__ = -1; \ |
} \ |
ENDTRY \ |
if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \ |
cma__bugcheck ("cma__ts_open2: one of fd's is too large"); \ |
return __res__; \ |
} |
|
/* |
* INTERNAL INTERFACES |
*/ |
extern void cma__close_general (int); |
|
extern void |
cma__init_thread_io (void); |
|
extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *); |
|
extern void cma__io_epilog (cma__t_io_type,int); |
|
extern void cma__io_prolog (cma__t_io_type,int); |
|
extern void cma__io_wait (cma__t_io_type,int); |
|
extern void cma__open_general (int); |
|
extern void cma__reinit_thread_io (int); |
|
extern void cma__set_nonblocking (int); |
|
extern void cma__set_user_nonblock_flags (int,int); |
|
extern cma_t_boolean |
cma__is_open (int fd); |
|
|
#endif |
|
|
/cma_sequence.h
0,0 → 1,56
/* |
* (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. |
* (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY |
* (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION |
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems |
* To anyone who acknowledges that this file is provided "AS IS" without |
* any express or implied warranty: permission to use, copy, modify, and |
* distribute this file for any purpose is hereby granted without fee, |
* provided that the above copyright notices and this notice appears in |
* all source code copies, and that none of the names listed above be used |
* in advertising or publicity pertaining to distribution of the software |
* without specific, written prior permission. None of these organizations |
* makes any representations about the suitability of this software for |
* any purpose. |
*/ |
/* |
* Header file for sequence generator functions |
*/ |
|
#ifndef CMA_SEQUENCE |
#define CMA_SEQUENCE |
|
/* |
* INCLUDE FILES |
*/ |
|
/* |
* CONSTANTS AND MACROS |
*/ |
|
/* |
* TYPEDEFS |
*/ |
|
#ifndef __STDC__ |
struct CMA__T_INT_MUTEX; |
#endif |
|
typedef struct CMA__T_SEQUENCE { |
struct CMA__T_INT_MUTEX *mutex; /* Serialize access to counter */ |
cma_t_natural seq; /* Sequence number for object */ |
} cma__t_sequence; |
|
/* |
* GLOBAL DATA |
*/ |
|
/* |
* INTERNAL INTERFACES |
*/ |
|
extern cma_t_natural cma__assign_sequence (cma__t_sequence *); |
|
extern void cma__init_sequence (cma__t_sequence *); |
|
#endif |