blob: 96376f2f72e2b32ba8675afeaae3cfdbe0ec4edf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef THREAD_PRIVATE_H
#define THREAD_PRIVATE_H
#include <assert.h>
#include <stdlib.h>
#include <open/types.h>
#include <open/hythread_ext.h>
#include <open/ncai_thread.h>
#include <apr_pools.h>
#include <apr_thread_mutex.h>
#include <apr_thread_cond.h>
#include <apr_thread_rwlock.h>
#include <apr_portable.h>
#include <assert.h>
#ifdef __linux__
#include <pthread.h>
#endif // __linux__
#if 1
#define CTRACE(a)
#else
#define CTRACE(a) printf a; printf("\n"); fflush(stdout)
#endif
#define DIE(a) \
printf("Thread manager aborted\n"); \
printf a; printf("\n"); fflush(stdout); \
exit(55);
// FIXME move to the global header, add error converter
#define RET_ON_ERROR(stat) if (stat) { return -1; }
#define CONVERT_ERROR(stat) (stat)
#define FAST_LOCAL_STORAGE_SIZE 10
#define HY_FAT_LOCK_ID_OFFSET 11 // fat lock ID offset within lockword
#define HY_FAT_LOCK_ID_MASK 0xFFFFF // nonzero bits (starting from 0 bit) to mask fat lock ID
#define HY_FAT_TABLE_ENTRIES (16*1024) // fat lock table is exapandible by adding new table
#define HY_MAX_FAT_LOCKS (HY_FAT_LOCK_ID_MASK + 1)// max total count of fat locks
// max count of tables for exapansion
#define HY_MAX_FAT_TABLES ((HY_MAX_FAT_LOCKS + HY_FAT_TABLE_ENTRIES - 1)/HY_FAT_TABLE_ENTRIES)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern hythread_group_t TM_DEFAULT_GROUP;
/**
* current capacity of the thread local storage
*/
extern int16 tm_tls_capacity;
/**
* current capacity of the thread local storage
*/
extern int16 tm_tls_size;
typedef struct HyThreadLibraryInternal {
IDATA a;
osmutex_t TM_LOCK;
IDATA nondaemon_thread_count;
hycond_t nondaemon_thread_cond;
} HyThreadLibraryInternal;
/**
* hythread_group_t pointer to the first element in the thread group
*/
typedef struct HyThreadGroup {
/**
* Pointer to the first thread in the list of threads
* contained in this group
*/
hythread_t thread_list;
/**
* Pointer to the first thread in the list of threads
* contained in this group
*/
hythread_t thread_list_tail;
/**
* Number of threads in this group
*/
int threads_count;
/**
* Group index or key for search purposes
*/
int group_index;
/**
* Memory pool to place created threads into.
*/
apr_pool_t* pool;
/**
*
*/
hythread_group_t next;
/**
*
*/
hythread_group_t prev;
} HyThreadGroup;
/**
* Fat monitor structure.
*
* A simple combination of conditional variable and fat lock.
*/
typedef struct HyThreadMonitor {
/// Monitor mutex.
osmutex_t mutex;
/// Monitor condition varibale.
hycond_t condition;
/// Mutex recurtion count.
IDATA recursion_count;
/// Current mutex owner.
hythread_t owner;
/// Number of threads waiting on a condition variable
/// or queued to acquire a monitor mutex after wakeup
int wait_count;
/// Number of notify events sent by the user,
/// it is bounded by the wait_count
int notify_count;
/// Owner thread ID.
IDATA thread_id;
UDATA flags;
const char *name;
} HyThreadMonitor;
/**
* Count down latch
*/
typedef struct HyLatch {
/**
* Latch count
*/
IDATA count;
/**
* Condition event used to signal threads which are waiting on the latch.
*/
hycond_t condition;
/**
* Mutex associated with the latch data.
*/
osmutex_t mutex;
} HyLatch;
/**
* Semaphore
*/
typedef struct HySemaphore {
/**
* Semaphore count
*/
int count;
/**
* Semaphore max count
*/
int max_count;
/**
* Condition event used to signal threads which are waiting on the semaphore.
*/
hycond_t condition;
/**
* Mutex associated with the semaphore data.
*/
osmutex_t mutex;
} HySemaphore;
/*
* Lock table which holds the mapping between LockID and fat lock
* (OS fat_monitor) pointer.
*/
typedef enum hythread_locktable_state {
HYTHREAD_LOCKTABLE_IDLE,
HYTHREAD_LOCKTABLE_READING,
HYTHREAD_LOCKTABLE_WRITING
} hythread_locktable_state_t;
typedef struct HyFatLockTable {
// locktable itself
hythread_monitor_t* tables[HY_MAX_FAT_TABLES];
// mutex guarding locktable
osmutex_t mutex;
hycond_t read;
hycond_t write;
int readers_reading;
int readers_waiting;
int writers_waiting;
hythread_locktable_state_t state;
U_32 read_count;
// table of live objects (updated during each major GC)
unsigned char *live_objs;
// size of locktable
U_32 size;
// used to scan the lock table for the next available entry
U_32 array_cursor;
} HyFatLockTable;
// Global variables
extern hythread_group_t group_list; // list of thread groups
extern IDATA groups_count; // number of thread groups
extern apr_pool_t *TM_POOL; //global APR pool for thread manager
extern apr_threadkey_t *TM_THREAD_KEY; // Key used to store tm_thread_t structure in TLS
extern int max_group_index; // max number of groups
extern HyFatLockTable *lock_table;
#define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads
/**
* Internal TM functions
*/
IDATA VMCALL hythread_get_group(hythread_group_t *group, hythread_t thread);
/**
* Auxiliary function to throw java.lang.InterruptedException
*/
void throw_interrupted_exception(void);
hythread_group_t get_java_thread_group(void);
/**
* Thread cancellation, being used at VM shutdown through
* tmj_cancel_all_threads() method call to terminate all java
* threads at shutdown.
*/
typedef void (*tm_thread_event_callback_proc)(void);
IDATA VMCALL set_safepoint_callback(hythread_t thread, tm_thread_event_callback_proc callback);
IDATA acquire_start_lock(void);
IDATA release_start_lock(void);
IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable);
IDATA condvar_wait_impl(hycond_t *cond, osmutex_t *mutex, I_64 ms, IDATA nano, IDATA interruptable);
IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA interruptable);
IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano, IDATA interruptable);
IDATA sem_wait_impl(hysem_t sem, I_64 ms, IDATA nano, IDATA interruptable);
/*
* portability functions, private for thread module
*/
int os_cond_timedwait(hycond_t *cond, osmutex_t *mutex, I_64 ms, IDATA nano);
#ifdef __cplusplus
}
#endif
#endif /* THREAD_PRIVATE_H */