Starting release 0.7.0
[parrot.git] / src / stm / stm_internal.h
blobad2275966da1435420e1fe949c1fbd550e7272f6
1 /*
2 * $Id$
3 * Copyright (C) 2006-2008, The Perl Foundation.
4 */
6 #ifndef PARROT_STM_INTERNAL_H_GUARD
7 #define PARROT_STM_INTERNAL_H_GUARD
9 #include <parrot/parrot.h>
10 #include <parrot/stm/backend.h>
11 #include "stm_waitlist.h"
13 #if STM_PROFILE
15 # define CYCLE_BUCKETS 20
16 # define TIME_BUCKETS 20
17 # define PROFILE(log) (log)->profile
18 # define PROFILE_WAIT(log, time, cycles) \
19 do { \
20 FLOATVAL the_time = (time); \
21 int time_bucket = ceil(the_time * 200.0); \
22 int cycle_bucket = (cycles) - 1; \
23 struct STM_profile_data *profile = &PROFILE(log); \
24 if ((cycles) == 0) { \
25 ++profile->num_non_waits; \
26 } \
27 else { \
28 if (time_bucket >= TIME_BUCKETS) { \
29 time_bucket = TIME_BUCKETS - 1; \
30 } \
31 else if (time_bucket == 0) { \
32 abort(); \
33 time_bucket = 0; \
34 } \
35 if (cycle_bucket >= CYCLE_BUCKETS) { \
36 cycle_bucket = CYCLE_BUCKETS - 1; \
37 } \
38 ++profile->num_waits; \
39 ++profile->wait_cycles[cycle_bucket]; \
40 ++profile->wait_time[time_bucket]; \
41 profile->total_wait_time += the_time; \
42 profile->total_wait_cycles += (cycles); \
43 } \
44 } while (0)
46 # define PROFILE_TRIED_COMMIT(log) \
47 ++PROFILE(log).attempted_commits
48 # define PROFILE_FAILED_COMMIT(log) \
49 ++PROFILE(log).failed_commits
50 # define PROFILE_ABORTED(profile) \
51 ++PROFILE(log).num_aborts
53 typedef struct STM_profile_data {
54 long attempted_commits;
55 long failed_commits;
56 long num_aborts;
57 long num_non_waits;
58 long num_waits;
59 long wait_cycles[CYCLE_BUCKETS];
60 long wait_time[TIME_BUCKETS];
61 double total_wait_time;
62 long total_wait_cycles;
63 } STM_profile_data;
65 #else
67 # define PROFILE(x)
68 # define PROFILE_TRIED_COMMIT(x)
69 # define PROFILE_FAILED_COMMIT(x)
70 # define PROFILE_ABORTED(x)
71 # define PROFILE_WAIT(x, y, z)
73 #endif
75 typedef struct Parrot_STM_PMC_handle_data {
76 Buffer buf;
77 Parrot_atomic_pointer owner_or_version;
78 void * volatile last_version;
79 PMC *value;
80 STM_waitlist change_waitlist;
81 } Parrot_STM_PMC_handle_data;
83 struct STM_write_record {
84 Parrot_STM_PMC_handle handle;
85 void *saw_version;
86 PMC *value;
89 struct STM_read_record {
90 Parrot_STM_PMC_handle handle;
91 void *saw_version;
92 PMC *value;
95 typedef struct STM_write_record STM_write_record;
96 typedef struct STM_read_record STM_read_record;
98 enum {
99 STM_STATUS_ACTIVE = 0,
100 STM_STATUS_ABORTED = 1,
101 STM_STATUS_COMMITTED = 2,
102 STM_STATUS_INVALID = 3
105 #define STM_START_RECORDS 32
107 #define STM_MAX_TX_DEPTH 32 /* TODO: remove limitation */
109 struct STM_tx_log_sub;
111 typedef struct STM_tx_log_sub STM_tx_log_sub;
113 /* log for a sub transaction */
114 struct STM_tx_log_sub {
115 Parrot_atomic_integer status;
116 /* for poor man's deadlock detection; based on Ennals' implementation */
117 Parrot_atomic_integer wait_length;
118 int first_write;
119 int first_read;
122 struct STM_tx_log {
123 int depth;
125 #if STM_PROFILE
126 STM_profile_data profile;
127 #endif
129 STM_tx_log_sub inner[STM_MAX_TX_DEPTH];
131 int last_write;
132 int last_read;
133 /* TODO: probably better to make these a list of hashes (one for each tx) */
134 STM_write_record *writes;
135 int writes_alloced;
136 STM_read_record *reads;
137 int reads_alloced;
139 struct waitlist_thread_data *waitlist_data;
142 struct STM_saved_tx_log {
143 int num_reads;
144 int num_writes;
145 STM_read_record *reads;
146 STM_write_record *writes;
148 typedef struct STM_saved_tx_log STM_saved_tx_log;
150 #endif /* PARROT_STM_INTERNAL_H_GUARD */
153 * Local variables:
154 * c-file-style: "parrot"
155 * End:
156 * vim: expandtab shiftwidth=4: