summaryrefslogtreecommitdiffhomepage
path: root/src/sync
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
committermidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
commitdd89bb8ad4fe184a34b5dbdda237e640fc82121b (patch)
tree5e80d2da35f5892f92be29f57982b2708e6bd99b /src/sync
parentdcdadc2702712fa750ed255ed1dfa354522797a0 (diff)
downloadntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.bz2
ntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.xz
entered advanced internal development stage.
Diffstat (limited to 'src/sync')
-rw-r--r--src/sync/ntapi_tt_create_event.c76
-rw-r--r--src/sync/ntapi_tt_sync_block.c283
-rw-r--r--src/sync/ntapi_tt_wait_for_dummy_event.c31
3 files changed, 390 insertions, 0 deletions
diff --git a/src/sync/ntapi_tt_create_event.c b/src/sync/ntapi_tt_create_event.c
new file mode 100644
index 0000000..3d81938
--- /dev/null
+++ b/src/sync/ntapi_tt_create_event.c
@@ -0,0 +1,76 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+static int32_t __cdecl __tt_create_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state,
+ __in uint32_t obj_attr)
+{
+ int32_t status;
+ nt_sqos sqos;
+ nt_oa oa;
+
+ /* validation */
+ if (!hevent)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* object attributes */
+ oa.len = sizeof(nt_object_attributes);
+ oa.root_dir = (void *)0;
+ oa.obj_name = (nt_unicode_string *)0;
+ oa.obj_attr = obj_attr;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ status = __ntapi->zw_create_event(
+ hevent,
+ NT_EVENT_ALL_ACCESS,
+ &oa,
+ event_type,
+ initial_state);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_create_inheritable_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state)
+{
+ return __tt_create_event(
+ hevent,
+ event_type,
+ initial_state,
+ NT_OBJ_INHERIT);
+}
+
+
+int32_t __stdcall __ntapi_tt_create_private_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state)
+{
+ return __tt_create_event(
+ hevent,
+ event_type,
+ initial_state,
+ 0);
+}
diff --git a/src/sync/ntapi_tt_sync_block.c b/src/sync/ntapi_tt_sync_block.c
new file mode 100644
index 0000000..e52dd77
--- /dev/null
+++ b/src/sync/ntapi_tt_sync_block.c
@@ -0,0 +1,283 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/nt_atomic.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+void __stdcall __ntapi_tt_sync_block_init(
+ __in nt_sync_block * sync_block,
+ __in uint32_t flags __optional,
+ __in int32_t srvtid __optional,
+ __in int32_t default_lock_tries __optional,
+ __in int64_t default_lock_wait __optional,
+ __in void * hsignal __optional)
+{
+ __ntapi->tt_aligned_block_memset(
+ sync_block,
+ 0,sizeof(*sync_block));
+
+ sync_block->lock_tries = default_lock_tries
+ ? default_lock_tries
+ : __NT_SYNC_BLOCK_LOCK_TRIES;
+
+ sync_block->lock_wait.quad = default_lock_wait
+ ? default_lock_wait
+ : (-1);
+
+ sync_block->flags = flags;
+ sync_block->srvtid = srvtid;
+ sync_block->hsignal = hsignal;
+
+ return;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_lock(
+ __in nt_sync_block * sync_block,
+ __in int32_t lock_tries __optional,
+ __in int64_t lock_wait __optional,
+ __in uint32_t * sig_flag __optional)
+{
+ int32_t status;
+ int32_t tid;
+ intptr_t lock;
+ void * hwait[2];
+ nt_timeout timeout;
+
+ /* validation */
+ if (sync_block->invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* already owned? */
+ tid = pe_get_current_thread_id();
+ if (sync_block->tid == tid) return NT_STATUS_SUCCESS;
+
+ /* yield to server? */
+ if ((sync_block->flags & NT_SYNC_BLOCK_YIELD_TO_SERVER) && (tid != sync_block->srvtid)) {
+ hwait[0] = sync_block->hserver;
+ hwait[1] = sync_block->hsignal;
+
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+
+ /* wait */
+ status = __ntapi->zw_wait_for_multiple_objects(
+ 2,
+ hwait,
+ NT_WAIT_ANY,
+ NT_SYNC_NON_ALERTABLE,
+ (nt_timeout *)0);
+
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+ }
+
+ /* first try */
+ lock = at_locked_cas_32(&sync_block->tid,0,tid);
+ if (lock && !--lock_tries) return NT_STATUS_NOT_LOCKED;
+
+ /* first-time contended case? */
+ if (lock && !sync_block->hwait) {
+ status = __ntapi->tt_create_inheritable_event(
+ &hwait[0],
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED);
+
+ if (status) return status;
+
+ lock = at_locked_cas(
+ (intptr_t *)&sync_block->hwait,
+ 0,(intptr_t)hwait);
+
+ if (lock)
+ __ntapi->zw_close(hwait);
+
+ /* try again without a wait */
+ lock = at_locked_cas_32(&sync_block->tid,0,tid);
+ }
+
+ /* contended case? */
+ if (lock) {
+ hwait[0] = sync_block->hwait;
+ hwait[1] = sync_block->hsignal;
+
+ lock_tries = lock_tries
+ ? lock_tries
+ : sync_block->lock_tries;
+
+ timeout.quad = lock_wait
+ ? lock_wait
+ : sync_block->lock_wait.quad;
+
+ for (; lock && lock_tries; lock_tries--) {
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+
+ /* wait */
+ status = __ntapi->zw_wait_for_multiple_objects(
+ 2,
+ &sync_block->hwait,
+ NT_WAIT_ANY,
+ NT_SYNC_NON_ALERTABLE,
+ &timeout);
+
+ /* check status */
+ if ((status != NT_STATUS_TIMEOUT) && ((uint32_t)status >= NT_STATUS_WAIT_CAP))
+ return status;
+
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+
+ /* try again */
+ lock = at_locked_cas_32(&sync_block->tid,0,tid);
+ };
+ }
+
+ if (lock) return NT_STATUS_NOT_LOCKED;
+
+ /* shared section support */
+ sync_block->pid = pe_get_current_process_id();
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_server_lock(
+ __in nt_sync_block * sync_block,
+ __in int32_t lock_tries __optional,
+ __in int64_t lock_wait __optional,
+ __in uint32_t * sig_flag __optional)
+{
+ int32_t status;
+
+ /* validation */
+ if (sync_block->invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ else if (sync_block->srvtid != pe_get_current_thread_id())
+ return NT_STATUS_RESOURCE_NOT_OWNED;
+
+ /* try once without yield request */
+ status = __ntapi_tt_sync_block_lock(
+ sync_block,
+ 1,
+ lock_wait,
+ sig_flag);
+
+ if (status == NT_STATUS_SUCCESS)
+ return status;
+
+ /* hserver */
+ if (!sync_block->hserver) {
+ status = __ntapi->tt_create_inheritable_event(
+ &sync_block->hserver,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED);
+
+ if (status) return status;
+ } else {
+ status = __ntapi->zw_reset_event(
+ &sync_block->hserver,
+ (int32_t *)0);
+
+ if (status) return status;
+ }
+
+ /* yield request: set */
+ sync_block->flags |= NT_SYNC_BLOCK_YIELD_TO_SERVER;
+
+ /* try again */
+ status = __ntapi_tt_sync_block_lock(
+ sync_block,
+ lock_tries,
+ lock_wait,
+ sig_flag);
+
+ /* yield request: unset */
+ sync_block->flags ^= NT_SYNC_BLOCK_YIELD_TO_SERVER;
+
+ __ntapi->zw_set_event(
+ sync_block->hserver,
+ (int32_t *)0);
+
+ /* (locking not guaranteed) */
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_unlock(
+ __in nt_sync_block * sync_block)
+{
+ int64_t cmp;
+
+ if (sync_block->invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ cmp = (int64_t)(pe_get_current_process_id()) << 32;
+ cmp += pe_get_current_thread_id();
+
+ if (cmp != at_locked_cas_64(
+ (int64_t *)&sync_block->tid,
+ cmp,0))
+ return NT_STATUS_RESOURCE_NOT_OWNED;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+void __stdcall __ntapi_tt_sync_block_validate(
+ __in nt_sync_block * sync_block)
+{
+ at_store_32(&sync_block->invalid,0);
+
+ return;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_invalidate(
+ __in nt_sync_block * sync_block)
+{
+ int32_t invalid;
+
+ if (!sync_block)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ invalid = at_locked_cas_32(
+ &sync_block->invalid,
+ 0,
+ 1);
+
+ if (invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_discard(
+ __in nt_sync_block * sync_block)
+{
+ if (!sync_block)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (sync_block->hwait)
+ __ntapi->zw_close(sync_block->hwait);
+
+ if (sync_block->hserver)
+ __ntapi->zw_close(sync_block->hserver);
+
+ __ntapi->tt_aligned_block_memset(sync_block,-1,sizeof(*sync_block));
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/sync/ntapi_tt_wait_for_dummy_event.c b/src/sync/ntapi_tt_wait_for_dummy_event.c
new file mode 100644
index 0000000..c7680c7
--- /dev/null
+++ b/src/sync/ntapi_tt_wait_for_dummy_event.c
@@ -0,0 +1,31 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_wait_for_dummy_event(void)
+{
+ /* wait forever without setting a break point and without spinning */
+
+ int32_t status;
+ void * hevent;
+
+ status = __ntapi->tt_create_inheritable_event(
+ &hevent,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ return __ntapi->zw_wait_for_single_object(hevent,0,0);
+
+ return status;
+}