forked from dlang/druntime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
roll back to a mostly-C version of monitor.
- Loading branch information
Showing
5 changed files
with
531 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| /** | ||
| * Implementation of support routines for synchronized blocks. | ||
| * | ||
| * Copyright: Copyright Digital Mars 2000 - 2010. | ||
| * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>. | ||
| * Authors: Walter Bright, Sean Kelly | ||
| */ | ||
|
|
||
| /* Copyright Digital Mars 2000 - 2010. | ||
| * Distributed under the Boost Software License, Version 1.0. | ||
| * (See accompanying file LICENSE_1_0.txt or copy at | ||
| * http://www.boost.org/LICENSE_1_0.txt) | ||
| */ | ||
|
|
||
| /* ================================= Win32 ============================ */ | ||
|
|
||
| #if _WIN32 | ||
|
|
||
| #include <windows.h> | ||
|
|
||
| /****************************************** | ||
| * Enter/exit critical section. | ||
| */ | ||
|
|
||
| /* We don't initialize critical sections unless we actually need them. | ||
| * So keep a linked list of the ones we do use, and in the static destructor | ||
| * code, walk the list and release them. | ||
| */ | ||
|
|
||
| typedef struct D_CRITICAL_SECTION | ||
| { | ||
| struct D_CRITICAL_SECTION *next; | ||
| CRITICAL_SECTION cs; | ||
| } D_CRITICAL_SECTION; | ||
|
|
||
| static D_CRITICAL_SECTION *dcs_list; | ||
| static D_CRITICAL_SECTION critical_section; | ||
| static volatile int inited; | ||
|
|
||
| void _d_criticalenter(D_CRITICAL_SECTION *dcs) | ||
| { | ||
| if (!dcs->next) | ||
| { | ||
| EnterCriticalSection(&critical_section.cs); | ||
| if (!dcs->next) // if, in the meantime, another thread didn't set it | ||
| { | ||
| dcs->next = dcs_list; | ||
| dcs_list = dcs; | ||
| InitializeCriticalSection(&dcs->cs); | ||
| } | ||
| LeaveCriticalSection(&critical_section.cs); | ||
| } | ||
| EnterCriticalSection(&dcs->cs); | ||
| } | ||
|
|
||
| void _d_criticalexit(D_CRITICAL_SECTION *dcs) | ||
| { | ||
| LeaveCriticalSection(&dcs->cs); | ||
| } | ||
|
|
||
| void _STI_critical_init() | ||
| { | ||
| if (!inited) | ||
| { InitializeCriticalSection(&critical_section.cs); | ||
| dcs_list = &critical_section; | ||
| inited = 1; | ||
| } | ||
| } | ||
|
|
||
| void _STD_critical_term() | ||
| { | ||
| if (inited) | ||
| { inited = 0; | ||
| while (dcs_list) | ||
| { | ||
| DeleteCriticalSection(&dcs_list->cs); | ||
| dcs_list = dcs_list->next; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endif | ||
|
|
||
| /* ================================= linux ============================ */ | ||
|
|
||
| #if linux || __APPLE__ || __FreeBSD__ | ||
|
|
||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <pthread.h> | ||
|
|
||
| // PTHREAD_MUTEX_RECURSIVE is the "standard" symbol, | ||
| // while the _NP version is specific to Linux | ||
| #if linux | ||
| # ifndef PTHREAD_MUTEX_RECURSIVE | ||
| # define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP | ||
| # endif | ||
| #endif | ||
|
|
||
| /****************************************** | ||
| * Enter/exit critical section. | ||
| */ | ||
|
|
||
| /* We don't initialize critical sections unless we actually need them. | ||
| * So keep a linked list of the ones we do use, and in the static destructor | ||
| * code, walk the list and release them. | ||
| */ | ||
|
|
||
| typedef struct D_CRITICAL_SECTION | ||
| { | ||
| struct D_CRITICAL_SECTION *next; | ||
| pthread_mutex_t cs; | ||
| } D_CRITICAL_SECTION; | ||
|
|
||
| static D_CRITICAL_SECTION *dcs_list; | ||
| static D_CRITICAL_SECTION critical_section; | ||
| static pthread_mutexattr_t _criticals_attr; | ||
|
|
||
| void _STI_critical_init(void); | ||
| void _STD_critical_term(void); | ||
|
|
||
| void _d_criticalenter(D_CRITICAL_SECTION *dcs) | ||
| { | ||
| if (!dcs_list) | ||
| { _STI_critical_init(); | ||
| atexit(_STD_critical_term); | ||
| } | ||
| //printf("_d_criticalenter(dcs = x%x)\n", dcs); | ||
| if (!dcs->next) | ||
| { | ||
| pthread_mutex_lock(&critical_section.cs); | ||
| if (!dcs->next) // if, in the meantime, another thread didn't set it | ||
| { | ||
| dcs->next = dcs_list; | ||
| dcs_list = dcs; | ||
| pthread_mutex_init(&dcs->cs, &_criticals_attr); | ||
| } | ||
| pthread_mutex_unlock(&critical_section.cs); | ||
| } | ||
| pthread_mutex_lock(&dcs->cs); | ||
| } | ||
|
|
||
| void _d_criticalexit(D_CRITICAL_SECTION *dcs) | ||
| { | ||
| //printf("_d_criticalexit(dcs = x%x)\n", dcs); | ||
| pthread_mutex_unlock(&dcs->cs); | ||
| } | ||
|
|
||
| void _STI_critical_init() | ||
| { | ||
| if (!dcs_list) | ||
| { //printf("_STI_critical_init()\n"); | ||
| pthread_mutexattr_init(&_criticals_attr); | ||
| pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); | ||
|
|
||
| // The global critical section doesn't need to be recursive | ||
| pthread_mutex_init(&critical_section.cs, 0); | ||
| dcs_list = &critical_section; | ||
| } | ||
| } | ||
|
|
||
| void _STD_critical_term() | ||
| { | ||
| if (dcs_list) | ||
| { //printf("_STI_critical_term()\n"); | ||
| while (dcs_list) | ||
| { | ||
| //printf("\tlooping... %x\n", dcs_list); | ||
| pthread_mutex_destroy(&dcs_list->cs); | ||
| dcs_list = dcs_list->next; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endif | ||
|
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| /** | ||
| * Common declarations for runtime implementation. | ||
| * | ||
| * Copyright: Copyright Digital Mars 2000 - 2010. | ||
| * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>. | ||
| * Authors: Walter Bright, Sean Kelly | ||
| */ | ||
|
|
||
| /* Copyright Digital Mars 2000 - 2010. | ||
| * Distributed under the Boost Software License, Version 1.0. | ||
| * (See accompanying file LICENSE_1_0.txt or copy at | ||
| * http://www.boost.org/LICENSE_1_0.txt) | ||
| */ | ||
| #include <stddef.h> | ||
|
|
||
| #if __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| struct ClassInfo; | ||
| struct Vtbl; | ||
|
|
||
| typedef struct Vtbl | ||
| { | ||
| size_t len; | ||
| void **vptr; | ||
| } Vtbl; | ||
|
|
||
| typedef struct Interface | ||
| { | ||
| struct ClassInfo *classinfo; | ||
| struct Vtbl vtbl; | ||
| int offset; | ||
| } Interface; | ||
|
|
||
| typedef struct Object | ||
| { | ||
| void **vptr; | ||
| void *monitor; | ||
| } Object; | ||
|
|
||
| typedef struct ClassInfo | ||
| { | ||
| Object object; | ||
|
|
||
| size_t initlen; | ||
| void *init; | ||
|
|
||
| size_t namelen; | ||
| char *name; | ||
|
|
||
| Vtbl vtbl; | ||
|
|
||
| size_t interfacelen; | ||
| Interface *interfaces; | ||
|
|
||
| struct ClassInfo *baseClass; | ||
|
|
||
| void *destructor; | ||
| void *invariant; | ||
|
|
||
| int flags; | ||
| } ClassInfo; | ||
|
|
||
| typedef struct Throwable | ||
| { | ||
| Object object; | ||
|
|
||
| size_t msglen; | ||
| char* msg; | ||
|
|
||
| size_t filelen; | ||
| char* file; | ||
|
|
||
| size_t line; | ||
|
|
||
| struct Interface *info; | ||
| struct Throwable *next; | ||
| } Throwable; | ||
|
|
||
| typedef struct Array | ||
| { | ||
| size_t length; | ||
| void *ptr; | ||
| } Array; | ||
|
|
||
| typedef struct Delegate | ||
| { | ||
| void *thisptr; | ||
| void (*funcptr)(); | ||
| } Delegate; | ||
|
|
||
| void _d_monitorenter(Object *h); | ||
| void _d_monitorexit(Object *h); | ||
|
|
||
| int _d_isbaseof(ClassInfo *b, ClassInfo *c); | ||
| Object *_d_dynamic_cast(Object *o, ClassInfo *ci); | ||
|
|
||
| Object * _d_newclass(ClassInfo *ci); | ||
| void _d_delclass(Object **p); | ||
|
|
||
| void _d_OutOfMemory(); | ||
|
|
||
| #if __cplusplus | ||
| } | ||
| #endif |
Oops, something went wrong.